comparison mercurial/patch.py @ 7521:ca044918fdf1

Merge with crew-stable
author Brendan Cully <brendan@kublai.com>
date Sun, 14 Dec 2008 23:05:18 -0800
parents e4ab4802f261 49f34b43cf90
children 4949729ee9ee
comparison
equal deleted inserted replaced
7520:e4ab4802f261 7521:ca044918fdf1
208 gp.oldpath = line[10:].rstrip() 208 gp.oldpath = line[10:].rstrip()
209 elif line.startswith('copy to '): 209 elif line.startswith('copy to '):
210 gp.path = line[8:].rstrip() 210 gp.path = line[8:].rstrip()
211 elif line.startswith('deleted file'): 211 elif line.startswith('deleted file'):
212 gp.op = 'DELETE' 212 gp.op = 'DELETE'
213 # is the deleted file a symlink?
214 gp.setmode(int(line.rstrip()[-6:], 8))
213 elif line.startswith('new file mode '): 215 elif line.startswith('new file mode '):
214 gp.op = 'ADD' 216 gp.op = 'ADD'
215 gp.setmode(int(line.rstrip()[-6:], 8)) 217 gp.setmode(int(line.rstrip()[-6:], 8))
216 elif line.startswith('new mode '): 218 elif line.startswith('new mode '):
217 gp.setmode(int(line.rstrip()[-6:], 8)) 219 gp.setmode(int(line.rstrip()[-6:], 8))
362 if self.exists and h.createfile(): 364 if self.exists and h.createfile():
363 self.ui.warn(_("file %s already exists\n") % self.fname) 365 self.ui.warn(_("file %s already exists\n") % self.fname)
364 self.rej.append(h) 366 self.rej.append(h)
365 return -1 367 return -1
366 368
367 if isinstance(h, binhunk): 369 if isinstance(h, githunk):
368 if h.rmfile(): 370 if h.rmfile():
369 self.unlink(self.fname) 371 self.unlink(self.fname)
370 else: 372 else:
371 self.lines[:] = h.new() 373 self.lines[:] = h.new()
372 self.offset += len(h.new()) 374 self.offset += len(h.new())
652 return res 654 return res
653 655
654 def new(self, fuzz=0, toponly=False): 656 def new(self, fuzz=0, toponly=False):
655 return self.fuzzit(self.b, fuzz, toponly) 657 return self.fuzzit(self.b, fuzz, toponly)
656 658
657 class binhunk: 659 class githunk(object):
658 'A binary patch file. Only understands literals so far.' 660 """A git hunk"""
659 def __init__(self, gitpatch): 661 def __init__(self, gitpatch):
660 self.gitpatch = gitpatch 662 self.gitpatch = gitpatch
661 self.text = None 663 self.text = None
662 self.hunk = ['GIT binary patch\n'] 664 self.hunk = []
663 665
664 def createfile(self): 666 def createfile(self):
665 return self.gitpatch.op in ('ADD', 'RENAME', 'COPY') 667 return self.gitpatch.op in ('ADD', 'RENAME', 'COPY')
666 668
667 def rmfile(self): 669 def rmfile(self):
670 def complete(self): 672 def complete(self):
671 return self.text is not None 673 return self.text is not None
672 674
673 def new(self): 675 def new(self):
674 return [self.text] 676 return [self.text]
677
678 class binhunk(githunk):
679 'A binary patch file. Only understands literals so far.'
680 def __init__(self, gitpatch):
681 super(binhunk, self).__init__(gitpatch)
682 self.hunk = ['GIT binary patch\n']
675 683
676 def extract(self, lr): 684 def extract(self, lr):
677 line = lr.readline() 685 line = lr.readline()
678 self.hunk.append(line) 686 self.hunk.append(line)
679 while line and not line.startswith('literal '): 687 while line and not line.startswith('literal '):
698 if len(text) != size: 706 if len(text) != size:
699 raise PatchError(_('binary patch is %d bytes, not %d') % 707 raise PatchError(_('binary patch is %d bytes, not %d') %
700 len(text), size) 708 len(text), size)
701 self.text = text 709 self.text = text
702 710
711 class symlinkhunk(githunk):
712 """A git symlink hunk"""
713 def __init__(self, gitpatch, hunk):
714 super(symlinkhunk, self).__init__(gitpatch)
715 self.hunk = hunk
716
717 def complete(self):
718 return True
719
720 def fix_newline(self):
721 return
722
703 def parsefilename(str): 723 def parsefilename(str):
704 # --- filename \t|space stuff 724 # --- filename \t|space stuff
705 s = str[4:].rstrip('\r\n') 725 s = str[4:].rstrip('\r\n')
706 i = s.find('\t') 726 i = s.find('\t')
707 if i < 0: 727 if i < 0:
855 context = True 875 context = True
856 gpatch = changed.get(bfile) 876 gpatch = changed.get(bfile)
857 create = afile == '/dev/null' or gpatch and gpatch.op == 'ADD' 877 create = afile == '/dev/null' or gpatch and gpatch.op == 'ADD'
858 remove = bfile == '/dev/null' or gpatch and gpatch.op == 'DELETE' 878 remove = bfile == '/dev/null' or gpatch and gpatch.op == 'DELETE'
859 current_hunk = hunk(x, hunknum + 1, lr, context, create, remove) 879 current_hunk = hunk(x, hunknum + 1, lr, context, create, remove)
880 if remove:
881 gpatch = changed.get(afile[2:])
882 if gpatch and gpatch.mode[0]:
883 current_hunk = symlinkhunk(gpatch, current_hunk)
860 except PatchError, err: 884 except PatchError, err:
861 ui.debug(err) 885 ui.debug(err)
862 current_hunk = None 886 current_hunk = None
863 continue 887 continue
864 hunknum += 1 888 hunknum += 1
1036 dst = os.path.join(repo.root, gp.path) 1060 dst = os.path.join(repo.root, gp.path)
1037 # patch won't create empty files 1061 # patch won't create empty files
1038 if gp.op == 'ADD' and not os.path.exists(dst): 1062 if gp.op == 'ADD' and not os.path.exists(dst):
1039 flags = (isexec and 'x' or '') + (islink and 'l' or '') 1063 flags = (isexec and 'x' or '') + (islink and 'l' or '')
1040 repo.wwrite(gp.path, '', flags) 1064 repo.wwrite(gp.path, '', flags)
1041 else: 1065 elif gp.op != 'DELETE':
1042 util.set_flags(dst, islink, isexec) 1066 util.set_flags(dst, islink, isexec)
1043 cmdutil.addremove(repo, cfiles, similarity=similarity) 1067 cmdutil.addremove(repo, cfiles, similarity=similarity)
1044 files = patches.keys() 1068 files = patches.keys()
1045 files.extend([r for r in removes if r not in files]) 1069 files.extend([r for r in removes if r not in files])
1046 return util.sort(files) 1070 return util.sort(files)