[PATCH 2 of 4] BUGGY: merge: use ancestor filename from planning phase instead of filectx ancestor

Mads Kiilerich mads at kiilerich.com
Mon Feb 24 22:50:27 CST 2014


# HG changeset patch
# User Mads Kiilerich <madski at unity3d.com>
# Date 1393303803 -3600
#      Tue Feb 25 05:50:03 2014 +0100
# Node ID 252fe2a2bcab6c32d1ccae258577b54500b043f6
# Parent  fc9e91fa8deed5f9e056bc3f6b188e5f4dbbdc5e
BUGGY: merge: use ancestor filename from planning phase instead of filectx ancestor

test-merge-types.t changes a bit in flag merging. It relied on the
implementation detail that 100% identical revlog entries are reused. The revlog
reuse did that fctx.ancestor() saw an ancestor where there really not was one.

The other test changes are because the approach taken here fails when
copies.mergecopies doesn't detect/report when a file has been renamed the same
way on both sides :-(

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -158,7 +158,7 @@ def _checkcollision(repo, wmf, actions, 
             pmmf.discard(f)
         pmmf.add(fd)
     def mergeop(f, args):
-        f2, fd, move = args
+        f2, fa, fd, move = args
         if move:
             pmmf.discard(f)
         pmmf.add(fd)
@@ -288,7 +288,7 @@ def manifestmerge(repo, wctx, p2, pa, br
             elif nol and n1 == a: # local only changed 'x'
                 actions.append((f, "g", (fl1,), "remote is newer"))
             else: # both changed something
-                actions.append((f, "m", (f, f, False), "versions differ"))
+                actions.append((f, "m", (f, f, f, False), "versions differ"))
         elif f in copied: # files we'll deal with on m2 side
             pass
         elif n1 and f in movewithdir: # directory rename
@@ -297,7 +297,7 @@ def manifestmerge(repo, wctx, p2, pa, br
                             "remote renamed directory to " + f2))
         elif n1 and f in copy:
             f2 = copy[f]
-            actions.append((f, "m", (f2, f, False),
+            actions.append((f, "m", (f2, f2, f, False),
                             "local copied/moved to " + f2))
         elif n1 and f in ma: # clean, a different, no remote
             if n1 != ma[f]:
@@ -313,10 +313,10 @@ def manifestmerge(repo, wctx, p2, pa, br
         elif n2 and f in copy:
             f2 = copy[f]
             if f2 in m2:
-                actions.append((f2, "m", (f, f, False),
+                actions.append((f2, "m", (f, f2, f, False),
                                 "remote copied to " + f))
             else:
-                actions.append((f2, "m", (f, f, True),
+                actions.append((f2, "m", (f, f2, f, True),
                                 "remote moved to " + f))
         elif n2 and f not in ma:
             # local unknown, remote created: the logic is described by the
@@ -336,7 +336,7 @@ def manifestmerge(repo, wctx, p2, pa, br
             else:
                 different = _checkunknownfile(repo, wctx, p2, f)
                 if force and branchmerge and different:
-                    actions.append((f, "m", (f, f, False),
+                    actions.append((f, "m", (f, f, f, False), # f not in ma ...
                                     "remote differs from untracked local"))
                 elif not force and different:
                     aborts.append((f, "ud"))
@@ -449,7 +449,7 @@ def applyupdates(repo, actions, wctx, mc
         f, m, args, msg = a
         repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
         if m == "m": # merge
-            f2, fd, move = args
+            f2, fa, fd, move = args
             if fd == '.hgsubstate': # merged internally
                 continue
             repo.ui.debug("  preserving %s for resolve of %s\n" % (f, fd))
@@ -460,9 +460,9 @@ def applyupdates(repo, actions, wctx, mc
                     fca = fcl.p1()
                 else:
                     fca = repo.filectx(f, fileid=nullrev)
+            elif fa in actx:
+                fca = actx[fa]
             else:
-                fca = fcl.ancestor(fco, actx)
-            if not fca:
                 fca = repo.filectx(f, fileid=nullrev)
             ms.add(fcl, fco, fca, fd)
             if f != fd and move:
@@ -514,7 +514,7 @@ def applyupdates(repo, actions, wctx, mc
         f, m, args, msg = a
         progress(_updating, z + i + 1, item=f, total=numupdates, unit=_files)
         if m == "m": # merge
-            f2, fd, move = args
+            f2, fa, fd, move = args
             if fd == '.hgsubstate': # subrepo states need updating
                 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
                                  overwrite)
@@ -596,7 +596,7 @@ def recordupdates(repo, actions, branchm
             else:
                 repo.dirstate.normal(f)
         elif m == "m": # merge
-            f2, fd, move = args
+            f2, fa, fd, move = args
             if branchmerge:
                 # We've done a branch merge, mark this file as merged
                 # so that we properly record the merger later
diff --git a/tests/test-merge-types.t b/tests/test-merge-types.t
--- a/tests/test-merge-types.t
+++ b/tests/test-merge-types.t
@@ -268,6 +268,7 @@ h: l vs l, different
   merging b
   warning: conflicts during merge.
   merging b incomplete! (edit conflicts, then use 'hg resolve --mark')
+  warning: cannot merge flags for c
   merging d
   warning: internal:merge cannot merge symlinks for d
   merging d incomplete! (edit conflicts, then use 'hg resolve --mark')
@@ -328,6 +329,7 @@ h: l vs l, different
   merging b
   warning: conflicts during merge.
   merging b incomplete! (edit conflicts, then use 'hg resolve --mark')
+  warning: cannot merge flags for c
   merging d
   warning: internal:merge cannot merge symlinks for d
   merging d incomplete! (edit conflicts, then use 'hg resolve --mark')
@@ -355,7 +357,7 @@ h: l vs l, different
   2
   >>>>>>> other
   $ tellmeabout c
-  c is a plain file with content:
+  c is an executable file with content:
   x
   $ tellmeabout d
   d is an executable file with content:
diff --git a/tests/test-rename-merge2.t b/tests/test-rename-merge2.t
--- a/tests/test-rename-merge2.t
+++ b/tests/test-rename-merge2.t
@@ -345,7 +345,7 @@ args:
   updating: b 1/2 files (50.00%)
   picked tool 'python ../merge' for b (binary False symlink False)
   merging b
-  my b at 62e7bf090eba+ other b at 49b6d8032493 ancestor a at 924404dff337
+  my b at 62e7bf090eba+ other b at 49b6d8032493 ancestor b at 000000000000
   updating: rev 2/2 files (100.00%)
   picked tool 'python ../merge' for rev (binary False symlink False)
   merging rev


More information about the Mercurial-devel mailing list