diff mercurial/cmdutil.py @ 12874:bb7bf43b72fb stable

patch: fix copies when patching over uncommitted changed (issue2459)
author Patrick Mezard <pmezard@gmail.com>
date Thu, 28 Oct 2010 21:25:53 +0200
parents 642afc8f50e7
children 4ff61287bde2
line wrap: on
line diff
--- a/mercurial/cmdutil.py	Wed Oct 27 16:54:46 2010 -0500
+++ b/mercurial/cmdutil.py	Thu Oct 28 21:25:53 2010 +0200
@@ -348,7 +348,7 @@
 
     wctx = repo[None]
     for src, dst in copies:
-        wctx.copy(src, dst)
+        dirstatecopy(ui, repo, wctx, src, dst, cwd=cwd)
     if (not similarity) and removes:
         wctx.remove(sorted(removes), True)
 
@@ -367,6 +367,25 @@
     files.extend([r for r in removes if r not in files])
     return sorted(files)
 
+def dirstatecopy(ui, repo, wctx, src, dst, dryrun=False, cwd=None):
+    """Update the dirstate to reflect the intent of copying src to dst. For
+    different reasons it might not end with dst being marked as copied from src.
+    """
+    origsrc = repo.dirstate.copied(src) or src
+    if dst == origsrc: # copying back a copy?
+        if repo.dirstate[dst] not in 'mn' and not dryrun:
+            repo.dirstate.normallookup(dst)
+    else:
+        if repo.dirstate[origsrc] == 'a' and origsrc == src:
+            if not ui.quiet:
+                ui.warn(_("%s has not been committed yet, so no copy "
+                          "data will be stored for %s.\n")
+                        % (repo.pathto(origsrc, cwd), repo.pathto(dst, cwd)))
+            if repo.dirstate[dst] in '?r' and not dryrun:
+                wctx.add([dst])
+        elif not dryrun:
+            wctx.copy(origsrc, dst)
+
 def copy(ui, repo, pats, opts, rename=False):
     # called with the repo lock held
     #
@@ -458,21 +477,7 @@
         targets[abstarget] = abssrc
 
         # fix up dirstate
-        origsrc = repo.dirstate.copied(abssrc) or abssrc
-        if abstarget == origsrc: # copying back a copy?
-            if state not in 'mn' and not dryrun:
-                repo.dirstate.normallookup(abstarget)
-        else:
-            if repo.dirstate[origsrc] == 'a' and origsrc == abssrc:
-                if not ui.quiet:
-                    ui.warn(_("%s has not been committed yet, so no copy "
-                              "data will be stored for %s.\n")
-                            % (repo.pathto(origsrc, cwd), reltarget))
-                if repo.dirstate[abstarget] in '?r' and not dryrun:
-                    wctx.add([abstarget])
-            elif not dryrun:
-                wctx.copy(origsrc, abstarget)
-
+        dirstatecopy(ui, repo, wctx, abssrc, abstarget, dryrun=dryrun, cwd=cwd)
         if rename and not dryrun:
             wctx.remove([abssrc], not after)