diff tests/test-import-git.t @ 16506:fc4e0fecf403 stable

patch: fix patch hunk/metdata synchronization (issue3384) Git patches are parsed in two phases: 1) extract metadata, 2) parse actual deltas and merge them with the previous metadata. We do this to avoid dependency issues like "modify a; copy a to b", where "b" must be copied from the unmodified "a". Issue3384 is caused by flaky code I wrote to synchronize the patch metadata with the emitted hunk: if (gitpatches and (gitpatches[-1][0] == afile or gitpatches[-1][1] == bfile)): gp = gitpatches.pop()[2] With a patch like: diff --git a/a b/c copy from a copy to c --- a/a +++ b/c @@ -1,1 +1,2 @@ a +a @@ -2,1 +2,2 @@ a +a diff --git a/a b/a --- a/a +++ b/a @@ -1,1 +1,2 @@ a +b the first hunk of the first block is matched with the metadata for the block "diff --git a/a b/c", then the second hunk of the first block is matched with the metadata of the second block "diff --git a/a b/a", because of the "or" in the code paste above. Turning the "or" into an "and" is not enough as we have to deal with /dev/null cases for each file. We I remove this broken piece of code: # copy/rename + modify should modify target, not source if gp.op in ('COPY', 'DELETE', 'RENAME', 'ADD') or gp.mode: afile = bfile because "afile = bfile" set "afile" to stuff like "b/file" instead of "a/file", and because this only happens for git patches, which afile/bfile are ignored anyway by applydiff(). v2: - Avoid a traceback on git metadata desynchronization
author Patrick Mezard <patrick@mezard.eu>
date Sat, 21 Apr 2012 21:40:25 +0200
parents d7829b2ecf32
children a8065323c003
line wrap: on
line diff
--- a/tests/test-import-git.t	Sat Apr 21 10:23:47 2012 +0200
+++ b/tests/test-import-git.t	Sat Apr 21 21:40:25 2012 +0200
@@ -483,4 +483,28 @@
   ? b.rej
   ? linkb.rej
 
+Test corner case involving copies and multiple hunks (issue3384)
+
+  $ hg revert -qa
+  $ hg import --no-commit - <<EOF
+  > diff --git a/a b/c
+  > copy from a
+  > copy to c
+  > --- a/a
+  > +++ b/c
+  > @@ -1,1 +1,2 @@
+  >  a
+  > +a
+  > @@ -2,1 +2,2 @@
+  >  a
+  > +a
+  > diff --git a/a b/a
+  > --- a/a
+  > +++ b/a
+  > @@ -1,1 +1,2 @@
+  >  a
+  > +b
+  > EOF
+  applying patch from stdin
+
   $ cd ..