Patchwork [4,of,8,v2] merge: use ancestor filename from planning phase instead of filectx ancestor

login
register
mail settings
Submitter Mads Kiilerich
Date Feb. 25, 2014, 7:40 p.m.
Message ID <1729920d85210c7aa44d.1393357226@mk-desktop>
Download mbox | patch
Permalink /patch/3765/
State Superseded
Commit 0b50788c160c05962bc3d147431fd1bc61dc2f28
Headers show

Comments

Mads Kiilerich - Feb. 25, 2014, 7:40 p.m.
# HG changeset patch
# User Mads Kiilerich <madski@unity3d.com>
# Date 1393356608 -3600
#      Tue Feb 25 20:30:08 2014 +0100
# Node ID 1729920d85210c7aa44d6d656e935f1abe04bb41
# Parent  f8d9cb25960bcdbef913cfc181496bb22dee3ba2
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.

Patch

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)
@@ -293,7 +293,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, fa, 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
@@ -302,7 +302,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]:
@@ -318,10 +318,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
@@ -341,7 +341,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"))
@@ -454,7 +454,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))
@@ -465,9 +465,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:
@@ -519,7 +519,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)
@@ -601,7 +601,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: