Mercurial > hg-stable
comparison mercurial/patch.py @ 9598:a981ddb16b80
Merge with crew-stable
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Fri, 16 Oct 2009 00:06:23 +0200 |
parents | c156bf947e26 d08099e74b81 |
children | 5384a22ab698 |
comparison
equal
deleted
inserted
replaced
9597:fbed59b61a1c | 9598:a981ddb16b80 |
---|---|
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 # Ensure supplied data ends in fname, being a regular file or |
305 # a symlink. updatedir() will -too magically- take care of | |
306 # setting it to the proper type afterwards. | |
307 islink = os.path.islink(fname) | |
308 if islink: | |
309 fp = cStringIO.StringIO() | |
310 else: | |
311 fp = self.opener(fname, 'w') | |
303 try: | 312 try: |
304 if self.eol and self.eol != '\n': | 313 if self.eol and self.eol != '\n': |
305 for l in lines: | 314 for l in lines: |
306 if l and l[-1] == '\n': | 315 if l and l[-1] == '\n': |
307 l = l[:-1] + self.eol | 316 l = l[:-1] + self.eol |
308 fp.write(l) | 317 fp.write(l) |
309 else: | 318 else: |
310 fp.writelines(lines) | 319 fp.writelines(lines) |
320 if islink: | |
321 self.opener.symlink(fp.getvalue(), fname) | |
311 finally: | 322 finally: |
312 fp.close() | 323 fp.close() |
313 | 324 |
314 def unlink(self, fname): | 325 def unlink(self, fname): |
315 os.unlink(fname) | 326 os.unlink(fname) |
397 if self.exists and h.createfile(): | 408 if self.exists and h.createfile(): |
398 self.ui.warn(_("file %s already exists\n") % self.fname) | 409 self.ui.warn(_("file %s already exists\n") % self.fname) |
399 self.rej.append(h) | 410 self.rej.append(h) |
400 return -1 | 411 return -1 |
401 | 412 |
402 if isinstance(h, githunk): | 413 if isinstance(h, binhunk): |
403 if h.rmfile(): | 414 if h.rmfile(): |
404 self.unlink(self.fname) | 415 self.unlink(self.fname) |
405 else: | 416 else: |
406 self.lines[:] = h.new() | 417 self.lines[:] = h.new() |
407 self.offset += len(h.new()) | 418 self.offset += len(h.new()) |
663 return res | 674 return res |
664 | 675 |
665 def new(self, fuzz=0, toponly=False): | 676 def new(self, fuzz=0, toponly=False): |
666 return self.fuzzit(self.b, fuzz, toponly) | 677 return self.fuzzit(self.b, fuzz, toponly) |
667 | 678 |
668 class githunk(object): | 679 class binhunk: |
669 """A git hunk""" | 680 'A binary patch file. Only understands literals so far.' |
670 def __init__(self, gitpatch): | 681 def __init__(self, gitpatch): |
671 self.gitpatch = gitpatch | 682 self.gitpatch = gitpatch |
672 self.text = None | 683 self.text = None |
673 self.hunk = [] | 684 self.hunk = ['GIT binary patch\n'] |
674 | 685 |
675 def createfile(self): | 686 def createfile(self): |
676 return self.gitpatch.op in ('ADD', 'RENAME', 'COPY') | 687 return self.gitpatch.op in ('ADD', 'RENAME', 'COPY') |
677 | 688 |
678 def rmfile(self): | 689 def rmfile(self): |
681 def complete(self): | 692 def complete(self): |
682 return self.text is not None | 693 return self.text is not None |
683 | 694 |
684 def new(self): | 695 def new(self): |
685 return [self.text] | 696 return [self.text] |
686 | |
687 class binhunk(githunk): | |
688 'A binary patch file. Only understands literals so far.' | |
689 def __init__(self, gitpatch): | |
690 super(binhunk, self).__init__(gitpatch) | |
691 self.hunk = ['GIT binary patch\n'] | |
692 | 697 |
693 def extract(self, lr): | 698 def extract(self, lr): |
694 line = lr.readline() | 699 line = lr.readline() |
695 self.hunk.append(line) | 700 self.hunk.append(line) |
696 while line and not line.startswith('literal '): | 701 while line and not line.startswith('literal '): |
715 if len(text) != size: | 720 if len(text) != size: |
716 raise PatchError(_('binary patch is %d bytes, not %d') % | 721 raise PatchError(_('binary patch is %d bytes, not %d') % |
717 len(text), size) | 722 len(text), size) |
718 self.text = text | 723 self.text = text |
719 | 724 |
720 class symlinkhunk(githunk): | |
721 """A git symlink hunk""" | |
722 def __init__(self, gitpatch, hunk): | |
723 super(symlinkhunk, self).__init__(gitpatch) | |
724 self.hunk = hunk | |
725 | |
726 def complete(self): | |
727 return True | |
728 | |
729 def fix_newline(self): | |
730 return | |
731 | |
732 def parsefilename(str): | 725 def parsefilename(str): |
733 # --- filename \t|space stuff | 726 # --- filename \t|space stuff |
734 s = str[4:].rstrip('\r\n') | 727 s = str[4:].rstrip('\r\n') |
735 i = s.find('\t') | 728 i = s.find('\t') |
736 if i < 0: | 729 if i < 0: |
873 context = True | 866 context = True |
874 gpatch = changed.get(bfile) | 867 gpatch = changed.get(bfile) |
875 create = afile == '/dev/null' or gpatch and gpatch.op == 'ADD' | 868 create = afile == '/dev/null' or gpatch and gpatch.op == 'ADD' |
876 remove = bfile == '/dev/null' or gpatch and gpatch.op == 'DELETE' | 869 remove = bfile == '/dev/null' or gpatch and gpatch.op == 'DELETE' |
877 current_hunk = hunk(x, hunknum + 1, lr, context, create, remove) | 870 current_hunk = hunk(x, hunknum + 1, lr, context, create, remove) |
878 if remove: | |
879 gpatch = changed.get(afile[2:]) | |
880 if gpatch and gpatch.mode[0]: | |
881 current_hunk = symlinkhunk(gpatch, current_hunk) | |
882 except PatchError, err: | 871 except PatchError, err: |
883 ui.debug(err) | 872 ui.debug(err) |
884 current_hunk = None | 873 current_hunk = None |
885 continue | 874 continue |
886 hunknum += 1 | 875 hunknum += 1 |