mercurial/patch.py
changeset 9585 ea1935e2020a
parent 9573 b8352a3617f3
child 9586 d08099e74b81
equal deleted inserted replaced
9575:5e44d9e562bc 9585:ea1935e2020a
   290         self.fileprinted = False
   290         self.fileprinted = False
   291         self.printfile(False)
   291         self.printfile(False)
   292         self.hunks = 0
   292         self.hunks = 0
   293 
   293 
   294     def readlines(self, fname):
   294     def readlines(self, fname):
       
   295         if os.path.islink(fname):
       
   296             return [os.readlink(fname)]
   295         fp = self.opener(fname, 'r')
   297         fp = self.opener(fname, 'r')
   296         try:
   298         try:
   297             return list(linereader(fp, self.eol is not None))
   299             return list(linereader(fp, self.eol is not None))
   298         finally:
   300         finally:
   299             fp.close()
   301             fp.close()
   300 
   302 
   301     def writelines(self, fname, lines):
   303     def writelines(self, fname, lines):        
   302         fp = self.opener(fname, 'w')
   304         fp = self.opener(fname, 'w')
   303         try:
   305         try:
   304             if self.eol and self.eol != '\n':
   306             if self.eol and self.eol != '\n':
   305                 for l in lines:
   307                 for l in lines:
   306                     if l and l[-1] == '\n':
   308                     if l and l[-1] == '\n':
   403         if self.exists and h.createfile():
   405         if self.exists and h.createfile():
   404             self.ui.warn(_("file %s already exists\n") % self.fname)
   406             self.ui.warn(_("file %s already exists\n") % self.fname)
   405             self.rej.append(h)
   407             self.rej.append(h)
   406             return -1
   408             return -1
   407 
   409 
   408         if isinstance(h, githunk):
   410         if isinstance(h, binhunk):
   409             if h.rmfile():
   411             if h.rmfile():
   410                 self.unlink(self.fname)
   412                 self.unlink(self.fname)
   411             else:
   413             else:
   412                 self.lines[:] = h.new()
   414                 self.lines[:] = h.new()
   413                 self.offset += len(h.new())
   415                 self.offset += len(h.new())
   694         return res
   696         return res
   695 
   697 
   696     def new(self, fuzz=0, toponly=False):
   698     def new(self, fuzz=0, toponly=False):
   697         return self.fuzzit(self.b, fuzz, toponly)
   699         return self.fuzzit(self.b, fuzz, toponly)
   698 
   700 
   699 class githunk(object):
   701 class binhunk:
   700     """A git hunk"""
   702     'A binary patch file. Only understands literals so far.'
   701     def __init__(self, gitpatch):
   703     def __init__(self, gitpatch):
   702         self.gitpatch = gitpatch
   704         self.gitpatch = gitpatch
   703         self.text = None
   705         self.text = None
   704         self.hunk = []
   706         self.hunk = ['GIT binary patch\n']
   705 
   707 
   706     def createfile(self):
   708     def createfile(self):
   707         return self.gitpatch.op in ('ADD', 'RENAME', 'COPY')
   709         return self.gitpatch.op in ('ADD', 'RENAME', 'COPY')
   708 
   710 
   709     def rmfile(self):
   711     def rmfile(self):
   712     def complete(self):
   714     def complete(self):
   713         return self.text is not None
   715         return self.text is not None
   714 
   716 
   715     def new(self):
   717     def new(self):
   716         return [self.text]
   718         return [self.text]
   717 
       
   718 class binhunk(githunk):
       
   719     'A binary patch file. Only understands literals so far.'
       
   720     def __init__(self, gitpatch):
       
   721         super(binhunk, self).__init__(gitpatch)
       
   722         self.hunk = ['GIT binary patch\n']
       
   723 
   719 
   724     def extract(self, lr):
   720     def extract(self, lr):
   725         line = lr.readline()
   721         line = lr.readline()
   726         self.hunk.append(line)
   722         self.hunk.append(line)
   727         while line and not line.startswith('literal '):
   723         while line and not line.startswith('literal '):
   746         if len(text) != size:
   742         if len(text) != size:
   747             raise PatchError(_('binary patch is %d bytes, not %d') %
   743             raise PatchError(_('binary patch is %d bytes, not %d') %
   748                              len(text), size)
   744                              len(text), size)
   749         self.text = text
   745         self.text = text
   750 
   746 
   751 class symlinkhunk(githunk):
       
   752     """A git symlink hunk"""
       
   753     def __init__(self, gitpatch, hunk):
       
   754         super(symlinkhunk, self).__init__(gitpatch)
       
   755         self.hunk = hunk
       
   756 
       
   757     def complete(self):
       
   758         return True
       
   759 
       
   760     def fix_newline(self):
       
   761         return
       
   762 
       
   763 def parsefilename(str):
   747 def parsefilename(str):
   764     # --- filename \t|space stuff
   748     # --- filename \t|space stuff
   765     s = str[4:].rstrip('\r\n')
   749     s = str[4:].rstrip('\r\n')
   766     i = s.find('\t')
   750     i = s.find('\t')
   767     if i < 0:
   751     if i < 0:
   895                     context = True
   879                     context = True
   896                 gpatch = changed.get(bfile)
   880                 gpatch = changed.get(bfile)
   897                 create = afile == '/dev/null' or gpatch and gpatch.op == 'ADD'
   881                 create = afile == '/dev/null' or gpatch and gpatch.op == 'ADD'
   898                 remove = bfile == '/dev/null' or gpatch and gpatch.op == 'DELETE'
   882                 remove = bfile == '/dev/null' or gpatch and gpatch.op == 'DELETE'
   899                 current_hunk = hunk(x, hunknum + 1, lr, context, create, remove)
   883                 current_hunk = hunk(x, hunknum + 1, lr, context, create, remove)
   900                 if remove:
       
   901                     gpatch = changed.get(afile[2:])
       
   902                     if gpatch and gpatch.mode[0]:
       
   903                         current_hunk = symlinkhunk(gpatch, current_hunk)
       
   904             except PatchError, err:
   884             except PatchError, err:
   905                 ui.debug(err)
   885                 ui.debug(err)
   906                 current_hunk = None
   886                 current_hunk = None
   907                 continue
   887                 continue
   908             hunknum += 1
   888             hunknum += 1