##// END OF EJS Templates
patch: pass linereader to scangitpatch(), extract from iterhunks()...
Patrick Mezard -
r7152:f0055cec default
parent child Browse files
Show More
@@ -166,15 +166,9 b' class patchmeta:'
166 isexec = mode & 0100
166 isexec = mode & 0100
167 self.mode = (islink, isexec)
167 self.mode = (islink, isexec)
168
168
169 def readgitpatch(fp, firstline=None):
169 def readgitpatch(lr):
170 """extract git-style metadata about patches from <patchname>"""
170 """extract git-style metadata about patches from <patchname>"""
171
171
172 def reader(fp, firstline):
173 if firstline is not None:
174 yield firstline
175 for line in fp:
176 yield line
177
178 # Filter patch for git information
172 # Filter patch for git information
179 gitre = re.compile('diff --git a/(.*) b/(.*)')
173 gitre = re.compile('diff --git a/(.*) b/(.*)')
180 gp = None
174 gp = None
@@ -183,7 +177,7 b' def readgitpatch(fp, firstline=None):'
183 dopatch = 0
177 dopatch = 0
184
178
185 lineno = 0
179 lineno = 0
186 for line in reader(fp, firstline):
180 for line in lr:
187 lineno += 1
181 lineno += 1
188 if line.startswith('diff --git'):
182 if line.startswith('diff --git'):
189 m = gitre.match(line)
183 m = gitre.match(line)
@@ -461,7 +455,7 b' class hunk:'
461 self.lenb = int(self.lenb)
455 self.lenb = int(self.lenb)
462 self.starta = int(self.starta)
456 self.starta = int(self.starta)
463 self.startb = int(self.startb)
457 self.startb = int(self.startb)
464 diffhelpers.addlines(lr.fp, self.hunk, self.lena, self.lenb, self.a, self.b)
458 diffhelpers.addlines(lr, self.hunk, self.lena, self.lenb, self.a, self.b)
465 # if we hit eof before finishing out the hunk, the last line will
459 # if we hit eof before finishing out the hunk, the last line will
466 # be zero length. Lets try to fix it up.
460 # be zero length. Lets try to fix it up.
467 while len(self.hunk[-1]) == 0:
461 while len(self.hunk[-1]) == 0:
@@ -771,7 +765,8 b' class linereader:'
771 self.buf = []
765 self.buf = []
772
766
773 def push(self, line):
767 def push(self, line):
774 self.buf.append(line)
768 if line is not None:
769 self.buf.append(line)
775
770
776 def readline(self):
771 def readline(self):
777 if self.buf:
772 if self.buf:
@@ -780,6 +775,39 b' class linereader:'
780 return l
775 return l
781 return self.fp.readline()
776 return self.fp.readline()
782
777
778 def __iter__(self):
779 while 1:
780 l = self.readline()
781 if not l:
782 break
783 yield l
784
785 def scangitpatch(lr, firstline):
786 """
787 Git patches can emit:
788 - rename a to b
789 - change b
790 - copy a to c
791 - change c
792
793 We cannot apply this sequence as-is, the renamed 'a' could not be
794 found for it would have been renamed already. And we cannot copy
795 from 'b' instead because 'b' would have been changed already. So
796 we scan the git patch for copy and rename commands so we can
797 perform the copies ahead of time.
798 """
799 pos = 0
800 try:
801 pos = lr.fp.tell()
802 fp = lr.fp
803 except IOError:
804 fp = cStringIO.StringIO(lr.fp.read())
805 gitlr = linereader(fp)
806 gitlr.push(firstline)
807 (dopatch, gitpatches) = readgitpatch(gitlr)
808 fp.seek(pos)
809 return fp, dopatch, gitpatches
810
783 def iterhunks(ui, fp, sourcefile=None):
811 def iterhunks(ui, fp, sourcefile=None):
784 """Read a patch and yield the following events:
812 """Read a patch and yield the following events:
785 - ("file", afile, bfile, firsthunk): select a new target file.
813 - ("file", afile, bfile, firsthunk): select a new target file.
@@ -788,24 +816,6 b' def iterhunks(ui, fp, sourcefile=None):'
788 - ("git", gitchanges): current diff is in git format, gitchanges
816 - ("git", gitchanges): current diff is in git format, gitchanges
789 maps filenames to gitpatch records. Unique event.
817 maps filenames to gitpatch records. Unique event.
790 """
818 """
791
792 def scangitpatch(fp, firstline):
793 '''git patches can modify a file, then copy that file to
794 a new file, but expect the source to be the unmodified form.
795 So we scan the patch looking for that case so we can do
796 the copies ahead of time.'''
797
798 pos = 0
799 try:
800 pos = fp.tell()
801 except IOError:
802 fp = cStringIO.StringIO(fp.read())
803
804 (dopatch, gitpatches) = readgitpatch(fp, firstline)
805 fp.seek(pos)
806
807 return fp, dopatch, gitpatches
808
809 changed = {}
819 changed = {}
810 current_hunk = None
820 current_hunk = None
811 afile = ""
821 afile = ""
@@ -869,7 +879,7 b' def iterhunks(ui, fp, sourcefile=None):'
869 afile, bfile = m.group(1, 2)
879 afile, bfile = m.group(1, 2)
870 if not git:
880 if not git:
871 git = True
881 git = True
872 fp, dopatch, gitpatches = scangitpatch(fp, x)
882 fp, dopatch, gitpatches = scangitpatch(lr, x)
873 yield 'git', gitpatches
883 yield 'git', gitpatches
874 for gp in gitpatches:
884 for gp in gitpatches:
875 changed[gp.path] = gp
885 changed[gp.path] = gp
General Comments 0
You need to be logged in to leave comments. Login now