comparison mercurial/patch.py @ 13699:d3c0e0033f13

patch: fix hunk newlines when parsing hunks, not in iterhunks()
author Patrick Mezard <pmezard@gmail.com>
date Sun, 20 Mar 2011 00:08:44 +0100
parents 104c9ed93fc5
children 63307feb59dd
comparison
equal deleted inserted replaced
13698:f30ce5983896 13699:d3c0e0033f13
678 del self.hunk[-1] 678 del self.hunk[-1]
679 del self.a[-1] 679 del self.a[-1]
680 del self.b[-1] 680 del self.b[-1]
681 self.lena -= 1 681 self.lena -= 1
682 self.lenb -= 1 682 self.lenb -= 1
683 self._fixnewline(lr)
683 684
684 def read_context_hunk(self, lr): 685 def read_context_hunk(self, lr):
685 self.desc = lr.readline() 686 self.desc = lr.readline()
686 m = contextdesc.match(self.desc) 687 m = contextdesc.match(self.desc)
687 if not m: 688 if not m:
780 self.b.append(x[1:]) 781 self.b.append(x[1:])
781 # @@ -start,len +start,len @@ 782 # @@ -start,len +start,len @@
782 self.desc = "@@ -%d,%d +%d,%d @@\n" % (self.starta, self.lena, 783 self.desc = "@@ -%d,%d +%d,%d @@\n" % (self.starta, self.lena,
783 self.startb, self.lenb) 784 self.startb, self.lenb)
784 self.hunk[0] = self.desc 785 self.hunk[0] = self.desc
785 786 self._fixnewline(lr)
786 def fix_newline(self): 787
787 diffhelpers.fix_newline(self.hunk, self.a, self.b) 788 def _fixnewline(self, lr):
789 l = lr.readline()
790 if l.startswith('\ '):
791 diffhelpers.fix_newline(self.hunk, self.a, self.b)
792 else:
793 lr.push(l)
788 794
789 def complete(self): 795 def complete(self):
790 return len(self.a) == self.lena and len(self.b) == self.lenb 796 return len(self.a) == self.lena and len(self.b) == self.lenb
791 797
792 def createfile(self): 798 def createfile(self):
991 "file" event. 997 "file" event.
992 - ("git", gitchanges): current diff is in git format, gitchanges 998 - ("git", gitchanges): current diff is in git format, gitchanges
993 maps filenames to gitpatch records. Unique event. 999 maps filenames to gitpatch records. Unique event.
994 """ 1000 """
995 changed = {} 1001 changed = {}
996 current_hunk = None
997 afile = "" 1002 afile = ""
998 bfile = "" 1003 bfile = ""
999 state = None 1004 state = None
1000 hunknum = 0 1005 hunknum = 0
1001 emitfile = False 1006 emitfile = False
1009 while True: 1014 while True:
1010 newfile = newgitfile = False 1015 newfile = newgitfile = False
1011 x = lr.readline() 1016 x = lr.readline()
1012 if not x: 1017 if not x:
1013 break 1018 break
1014 if current_hunk:
1015 if x.startswith('\ '):
1016 current_hunk.fix_newline()
1017 yield 'hunk', current_hunk
1018 current_hunk = None
1019 if (state == BFILE and ((not context and x[0] == '@') or 1019 if (state == BFILE and ((not context and x[0] == '@') or
1020 ((context is not False) and x.startswith('***************')))): 1020 ((context is not False) and x.startswith('***************')))):
1021 if context is None and x.startswith('***************'): 1021 if context is None and x.startswith('***************'):
1022 context = True 1022 context = True
1023 gpatch = changed.get(bfile) 1023 gpatch = changed.get(bfile)
1024 create = afile == '/dev/null' or gpatch and gpatch.op == 'ADD' 1024 create = afile == '/dev/null' or gpatch and gpatch.op == 'ADD'
1025 remove = bfile == '/dev/null' or gpatch and gpatch.op == 'DELETE' 1025 remove = bfile == '/dev/null' or gpatch and gpatch.op == 'DELETE'
1026 current_hunk = hunk(x, hunknum + 1, lr, context, create, remove) 1026 h = hunk(x, hunknum + 1, lr, context, create, remove)
1027 hunknum += 1 1027 hunknum += 1
1028 if emitfile: 1028 if emitfile:
1029 emitfile = False 1029 emitfile = False
1030 yield 'file', (afile, bfile, current_hunk) 1030 yield 'file', (afile, bfile, h)
1031 yield 'hunk', h
1031 elif state == BFILE and x.startswith('GIT binary patch'): 1032 elif state == BFILE and x.startswith('GIT binary patch'):
1032 current_hunk = binhunk(changed[bfile]) 1033 h = binhunk(changed[bfile])
1033 hunknum += 1 1034 hunknum += 1
1034 if emitfile: 1035 if emitfile:
1035 emitfile = False 1036 emitfile = False
1036 yield 'file', ('a/' + afile, 'b/' + bfile, current_hunk) 1037 yield 'file', ('a/' + afile, 'b/' + bfile, h)
1037 current_hunk.extract(lr) 1038 h.extract(lr)
1039 yield 'hunk', h
1038 elif x.startswith('diff --git'): 1040 elif x.startswith('diff --git'):
1039 # check for git diff, scanning the whole patch file if needed 1041 # check for git diff, scanning the whole patch file if needed
1040 m = gitre.match(x) 1042 m = gitre.match(x)
1041 if m: 1043 if m:
1042 afile, bfile = m.group(1, 2) 1044 afile, bfile = m.group(1, 2)
1081 1083
1082 if newgitfile or newfile: 1084 if newgitfile or newfile:
1083 emitfile = True 1085 emitfile = True
1084 state = BFILE 1086 state = BFILE
1085 hunknum = 0 1087 hunknum = 0
1086 if current_hunk:
1087 if current_hunk.complete():
1088 yield 'hunk', current_hunk
1089 else:
1090 raise PatchError(_("malformed patch %s %s") % (afile,
1091 current_hunk.desc))
1092 1088
1093 def applydiff(ui, fp, changed, strip=1, eolmode='strict'): 1089 def applydiff(ui, fp, changed, strip=1, eolmode='strict'):
1094 """Reads a patch from fp and tries to apply it. 1090 """Reads a patch from fp and tries to apply it.
1095 1091
1096 The dict 'changed' is filled in with all of the filenames changed 1092 The dict 'changed' is filled in with all of the filenames changed