changeset 6295:bace1990ab12

patch: fix corner case with update + copy patch handling (issue 937) The self patching of files when diffed with a backup is a bit peculiar to me. It makes sense in mpatch, that's less clear in mercurial patching code. Let's document and preserve it for now.
author Patrick Mezard <pmezard@gmail.com>
date Mon, 17 Mar 2008 23:36:45 +0100
parents 9cd6292abfdf
children a9e6b8875805
files mercurial/patch.py tests/test-import tests/test-import.out
diffstat 3 files changed, 36 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/patch.py	Mon Mar 17 14:51:41 2008 -0700
+++ b/mercurial/patch.py	Mon Mar 17 23:36:45 2008 +0100
@@ -800,13 +800,13 @@
             while i < pathlen - 1 and path[i] == '/':
                 i += 1
             count -= 1
-        return path[i:].rstrip()
+        return path[:i].lstrip(), path[i:].rstrip()
 
     nulla = afile_orig == "/dev/null"
     nullb = bfile_orig == "/dev/null"
-    afile = pathstrip(afile_orig, strip)
+    abase, afile = pathstrip(afile_orig, strip)
     gooda = not nulla and os.path.exists(afile)
-    bfile = pathstrip(bfile_orig, strip)
+    bbase, bfile = pathstrip(bfile_orig, strip)
     if afile == bfile:
         goodb = gooda
     else:
@@ -815,16 +815,20 @@
     if reverse:
         createfunc = hunk.rmfile
     missing = not goodb and not gooda and not createfunc()
+    # If afile is "a/b/foo" and bfile is "a/b/foo.orig" we assume the
+    # diff is between a file and its backup. In this case, the original
+    # file should be patched (see original mpatch code).
+    isbackup = (abase == bbase and bfile.startswith(afile))
     fname = None
     if not missing:
         if gooda and goodb:
-            fname = (afile in bfile) and afile or bfile
+            fname = isbackup and afile or bfile
         elif gooda:
             fname = afile
 
     if not fname:
         if not nullb:
-            fname = (afile in bfile) and afile or bfile
+            fname = isbackup and afile or bfile
         elif not nulla:
             fname = afile
         else:
--- a/tests/test-import	Mon Mar 17 14:51:41 2008 -0700
+++ b/tests/test-import	Mon Mar 17 23:36:45 2008 +0100
@@ -225,3 +225,22 @@
 hg manifest
 cd ..
 
+echo % 'test update+rename with common name (issue 927)'
+hg init t
+cd t
+touch a
+hg ci -Am t
+echo a > a
+# Here, bfile.startswith(afile)
+hg copy a a2
+hg ci -m copya
+hg export --git tip > copy.diff
+hg up -C 0
+hg import copy.diff
+echo % view a
+# a should contain an 'a'
+cat a
+echo % view a2
+# and a2 should have duplicated it
+cat a2
+cd ..
--- a/tests/test-import.out	Mon Mar 17 14:51:41 2008 -0700
+++ b/tests/test-import.out	Mon Mar 17 23:36:45 2008 +0100
@@ -232,3 +232,11 @@
 diff --git a/b b/b
 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
 applying remove.diff
+% test update+rename with common name (issue 927)
+adding a
+1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+applying copy.diff
+% view a
+a
+% view a2
+a