changeset 14534:ecc79816d31e

patch: fix patchmeta/hunk synchronization in iterhunks() Synchronizing on bfile does not work on file removal where bfile is /dev/null. We match items on afile or bfile instead. The incorrect code makes iterhunks() to emit patchmeta and hunks separately in some cases. This is currently hidden by applydiff() being too tolerant when processing patchmeta, and will be fixed later.
author Patrick Mezard <pmezard@gmail.com>
date Sun, 05 Jun 2011 22:24:19 +0200
parents aa12e1bbde10
children e597ef52a7c2
files mercurial/patch.py
diffstat 1 files changed, 10 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/patch.py	Sun Jun 05 22:24:11 2011 +0200
+++ b/mercurial/patch.py	Sun Jun 05 22:24:19 2011 +0200
@@ -1122,8 +1122,9 @@
             or (context is not False and x.startswith('***************'))
             or x.startswith('GIT binary patch')):
             gp = None
-            if gitpatches and gitpatches[-1][0] == bfile:
-                gp = gitpatches.pop()[1]
+            if (gitpatches and
+                (gitpatches[-1][0] == afile or gitpatches[-1][1] == bfile)):
+                gp = gitpatches.pop()[2]
             if x.startswith('GIT binary patch'):
                 h = binhunk(lr)
             else:
@@ -1141,17 +1142,17 @@
                 continue
             if gitpatches is None:
                 # scan whole input for git metadata
-                gitpatches = [('b/' + gp.path, gp) for gp
+                gitpatches = [('a/' + gp.path, 'b/' + gp.path, gp) for gp
                               in scangitpatch(lr, x)]
-                yield 'git', [g[1] for g in gitpatches
-                              if g[1].op in ('COPY', 'RENAME')]
+                yield 'git', [g[2] for g in gitpatches
+                              if g[2].op in ('COPY', 'RENAME')]
                 gitpatches.reverse()
             afile = 'a/' + m.group(1)
             bfile = 'b/' + m.group(2)
-            while bfile != gitpatches[-1][0]:
-                gp = gitpatches.pop()[1]
+            while afile != gitpatches[-1][0] and bfile != gitpatches[-1][1]:
+                gp = gitpatches.pop()[2]
                 yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp)
-            gp = gitpatches[-1][1]
+            gp = gitpatches[-1][2]
             # copy/rename + modify should modify target, not source
             if gp.op in ('COPY', 'DELETE', 'RENAME', 'ADD') or gp.mode:
                 afile = bfile
@@ -1189,7 +1190,7 @@
             hunknum = 0
 
     while gitpatches:
-        gp = gitpatches.pop()[1]
+        gp = gitpatches.pop()[2]
         yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp)
 
 def applydiff(ui, fp, changed, backend, store, strip=1, eolmode='strict'):