##// 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 166 isexec = mode & 0100
167 167 self.mode = (islink, isexec)
168 168
169 def readgitpatch(fp, firstline=None):
169 def readgitpatch(lr):
170 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 172 # Filter patch for git information
179 173 gitre = re.compile('diff --git a/(.*) b/(.*)')
180 174 gp = None
@@ -183,7 +177,7 b' def readgitpatch(fp, firstline=None):'
183 177 dopatch = 0
184 178
185 179 lineno = 0
186 for line in reader(fp, firstline):
180 for line in lr:
187 181 lineno += 1
188 182 if line.startswith('diff --git'):
189 183 m = gitre.match(line)
@@ -461,7 +455,7 b' class hunk:'
461 455 self.lenb = int(self.lenb)
462 456 self.starta = int(self.starta)
463 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 459 # if we hit eof before finishing out the hunk, the last line will
466 460 # be zero length. Lets try to fix it up.
467 461 while len(self.hunk[-1]) == 0:
@@ -771,7 +765,8 b' class linereader:'
771 765 self.buf = []
772 766
773 767 def push(self, line):
774 self.buf.append(line)
768 if line is not None:
769 self.buf.append(line)
775 770
776 771 def readline(self):
777 772 if self.buf:
@@ -780,6 +775,39 b' class linereader:'
780 775 return l
781 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 811 def iterhunks(ui, fp, sourcefile=None):
784 812 """Read a patch and yield the following events:
785 813 - ("file", afile, bfile, firsthunk): select a new target file.
@@ -788,24 +816,6 b' def iterhunks(ui, fp, sourcefile=None):'
788 816 - ("git", gitchanges): current diff is in git format, gitchanges
789 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 819 changed = {}
810 820 current_hunk = None
811 821 afile = ""
@@ -869,7 +879,7 b' def iterhunks(ui, fp, sourcefile=None):'
869 879 afile, bfile = m.group(1, 2)
870 880 if not git:
871 881 git = True
872 fp, dopatch, gitpatches = scangitpatch(fp, x)
882 fp, dopatch, gitpatches = scangitpatch(lr, x)
873 883 yield 'git', gitpatches
874 884 for gp in gitpatches:
875 885 changed[gp.path] = gp
General Comments 0
You need to be logged in to leave comments. Login now