changeset 20944:5b8d5803d7b7

merge: keep destination filename as key in actions for merge with dir rename Avoids None: local renamed directory to b/c -> d updating:None 1/1 files (100.00%) and makes it possible to compare/merge actions later.
author Mads Kiilerich <madski@unity3d.com>
date Sun, 02 Mar 2014 18:49:36 +0100
parents 003cb972178d
children 18adc15635a1
files mercurial/merge.py tests/test-rename-dir-merge.t
diffstat 2 files changed, 44 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/merge.py	Fri Feb 28 02:38:33 2014 +0100
+++ b/mercurial/merge.py	Sun Mar 02 18:49:36 2014 +0100
@@ -334,11 +334,13 @@
     def nop(f, args):
         pass
 
-    def renameop(f, args):
-        f2, fd, flags = args
-        if f:
-            pmmf.discard(f)
-        pmmf.add(fd)
+    def renamemoveop(f, args):
+        f2, flags = args
+        pmmf.discard(f2)
+        pmmf.add(f)
+    def renamegetop(f, args):
+        f2, flags = args
+        pmmf.add(f)
     def mergeop(f, args):
         f2, fa, fd, move, anc = args
         if move:
@@ -347,7 +349,8 @@
 
     opmap = {
         "a": addop,
-        "d": renameop,
+        "dm": renamemoveop,
+        "dg": renamegetop,
         "dr": nop,
         "e": nop,
         "f": addop, # untracked file should be kept in working directory
@@ -472,10 +475,10 @@
                                "versions differ"))
         elif f in copied: # files we'll deal with on m2 side
             pass
-        elif n1 and f in movewithdir: # directory rename
+        elif n1 and f in movewithdir: # directory rename, move local
             f2 = movewithdir[f]
-            actions.append((f, "d", (None, f2, fl1),
-                            "remote renamed directory to " + f2))
+            actions.append((f2, "dm", (f, fl1),
+                            "remote directory rename - move from " + f))
         elif n1 and f in copy:
             f2 = copy[f]
             actions.append((f, "m", (f2, f2, f, False, pa.node()),
@@ -492,8 +495,8 @@
                 actions.append((f, "r", None, "other deleted"))
         elif n2 and f in movewithdir:
             f2 = movewithdir[f]
-            actions.append((None, "d", (f, f2, fl2),
-                            "local renamed directory to " + f2))
+            actions.append((f2, "dg", (f, fl2),
+                            "local directory rename - get from " + f))
         elif n2 and f in copy:
             f2 = copy[f]
             if f2 in m2:
@@ -693,16 +696,17 @@
                     updated += 1
                 else:
                     merged += 1
-        elif m == "d": # directory rename
-            f2, fd, flags = args
-            if f:
-                repo.ui.note(_("moving %s to %s\n") % (f, fd))
-                audit(fd)
-                repo.wwrite(fd, wctx.filectx(f).data(), flags)
-                util.unlinkpath(repo.wjoin(f))
-            if f2:
-                repo.ui.note(_("getting %s to %s\n") % (f2, fd))
-                repo.wwrite(fd, mctx.filectx(f2).data(), flags)
+        elif m == "dm": # directory rename, move local
+            f0, flags = args
+            repo.ui.note(_("moving %s to %s\n") % (f0, f))
+            audit(f)
+            repo.wwrite(f, wctx.filectx(f0).data(), flags)
+            util.unlinkpath(repo.wjoin(f0))
+            updated += 1
+        elif m == "dg": # local directory rename, get
+            f0, flags = args
+            repo.ui.note(_("getting %s to %s\n") % (f0, f))
+            repo.wwrite(f, mctx.filectx(f0).data(), flags)
             updated += 1
         elif m == "dr": # divergent renames
             fl, = args
@@ -811,22 +815,25 @@
                     repo.dirstate.normallookup(fd)
                 if move:
                     repo.dirstate.drop(f)
-        elif m == "d": # directory rename
-            f2, fd, flag = args
-            if not f2 and f not in repo.dirstate:
+        elif m == "dm": # directory rename, move local
+            f0, flag = args
+            if f0 not in repo.dirstate:
                 # untracked file moved
                 continue
             if branchmerge:
-                repo.dirstate.add(fd)
-                if f:
-                    repo.dirstate.remove(f)
-                    repo.dirstate.copy(f, fd)
-                if f2:
-                    repo.dirstate.copy(f2, fd)
+                repo.dirstate.add(f)
+                repo.dirstate.remove(f0)
+                repo.dirstate.copy(f0, f)
             else:
-                repo.dirstate.normal(fd)
-                if f:
-                    repo.dirstate.drop(f)
+                repo.dirstate.normal(f)
+                repo.dirstate.drop(f0)
+        elif m == "dg": # directory rename, get
+            f0, flag = args
+            if branchmerge:
+                repo.dirstate.add(f)
+                repo.dirstate.copy(f0, f)
+            else:
+                repo.dirstate.normal(f)
 
 def update(repo, node, branchmerge, force, partial, ancestor=None,
            mergeancestor=False):
--- a/tests/test-rename-dir-merge.t	Fri Feb 28 02:38:33 2014 +0100
+++ b/tests/test-rename-dir-merge.t	Sun Mar 02 18:49:36 2014 +0100
@@ -41,16 +41,16 @@
    ancestor: f9b20c0d4c51, local: ce36d17b18fb+, remote: 397f8b00a740
    a/a: other deleted -> r
    a/b: other deleted -> r
-   a/c: remote renamed directory to b/c -> d
    b/a: remote created -> g
    b/b: remote created -> g
+   b/c: remote directory rename - move from a/c -> dm
   removing a/a
   removing a/b
   updating: a/b 2/5 files (40.00%)
   getting b/a
   getting b/b
   updating: b/b 4/5 files (80.00%)
-  updating: a/c 5/5 files (100.00%)
+  updating: b/c 5/5 files (100.00%)
   moving a/c to b/c (glob)
   3 files updated, 0 files merged, 2 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
@@ -88,8 +88,8 @@
   resolving manifests
    branchmerge: True, force: False, partial: False
    ancestor: f9b20c0d4c51, local: 397f8b00a740+, remote: ce36d17b18fb
-   None: local renamed directory to b/c -> d
-  updating:None 1/1 files (100.00%)
+   b/c: local directory rename - get from a/c -> dg
+  updating: b/c 1/1 files (100.00%)
   getting a/c to b/c
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)