diff mercurial/patch.py @ 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 9db24a36d182
children 65029a3aafc2
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: