Patchwork [2,of,3,cah,v2,+,bid] context: introduce merge.preferancestor for controlling which ancestor to pick

login
register
mail settings
Submitter Mads Kiilerich
Date April 17, 2014, 8:26 p.m.
Message ID <d656bfcd5c684e5bd74d.1397766381@localhost.localdomain>
Download mbox | patch
Permalink /patch/4408/
State Accepted
Commit 99b5eaf372a77e249f1481dc02bcc31a893d4901
Headers show

Comments

Mads Kiilerich - April 17, 2014, 8:26 p.m.
# HG changeset patch
# User Mads Kiilerich <madski@unity3d.com>
# Date 1393278134 -3600
#      Mon Feb 24 22:42:14 2014 +0100
# Node ID d656bfcd5c684e5bd74da09d5613e991ff786630
# Parent  5c14974073cf5b30d68c114c2a93942acf62bbf7
context: introduce merge.preferancestor for controlling which ancestor to pick

Multiple revisions can be specified in merge.preferancestor, separated by
whitespace. First match wins.

This makes it possible to overrule the default of picking the common ancestor
with the lowest hash value among the "best" (introduced in 3605d4e7e618).

This can for instance help with some merges where the 'wrong' ancestor is used.
There will thus be some overlap between this and the problems that can be
solved with a future 'consensus merge'.

Mercurial will show a note like
  note: using 40663881a6dd as ancestor of 3b08d01b0ab5 and adfe50279922
        alternatively, use --config merge.preferancestor=0f6b37dbe527
when the option is available, listing all the alternative ancestors.

Patch

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -396,7 +396,7 @@  class changectx(basectx):
 
     def ancestor(self, c2):
         """
-        return the ancestor context of self and c2
+        return the "best" ancestor context of self and c2
         """
         # deal with workingctxs
         n2 = c2._node
@@ -408,10 +408,19 @@  class changectx(basectx):
         elif len(cahs) == 1:
             anc = cahs[0]
         else:
-            anc = self._repo.changelog.ancestor(self._node, n2)
+            for r in self._repo.ui.configlist('merge', 'preferancestor'):
+                ctx = changectx(self._repo, r)
+                anc = ctx.node()
+                if anc in cahs:
+                    break
+            else:
+                anc = self._repo.changelog.ancestor(self._node, n2)
             self._repo.ui.status(
                 (_("note: using %s as ancestor of %s and %s\n") %
-                 (short(anc), short(self._node), short(n2))))
+                 (short(anc), short(self._node), short(n2))) +
+                ''.join(_("      alternatively, use --config "
+                          "merge.preferancestor=%s\n") %
+                        short(n) for n in sorted(cahs) if n != anc))
         return changectx(self._repo, anc)
 
     def descendant(self, other):
diff --git a/tests/test-merge-criss-cross.t b/tests/test-merge-criss-cross.t
--- a/tests/test-merge-criss-cross.t
+++ b/tests/test-merge-criss-cross.t
@@ -25,6 +25,7 @@  Criss cross merging
 
   $ hg up -r3
   note: using 0f6b37dbe527 as ancestor of adfe50279922 and cf89f02107e5
+        alternatively, use --config merge.preferancestor=40663881a6dd
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ echo '6 second change' > f2
   $ hg ci -m '6 second change f2'
@@ -75,6 +76,7 @@  Criss cross merging
 
   $ hg merge -v --debug --tool internal:dump 5
   note: using 0f6b37dbe527 as ancestor of 3b08d01b0ab5 and adfe50279922
+        alternatively, use --config merge.preferancestor=40663881a6dd
     searching for copies back to rev 3
   resolving manifests
    branchmerge: True, force: False, partial: False
@@ -111,4 +113,14 @@  Criss cross merging
   ==> f2.other <==
   2 first change
 
+  $ hg up -qC .
+  $ hg merge -v --tool internal:dump 5 --config merge.preferancestor="null 40663881 3b08d"
+  note: using 40663881a6dd as ancestor of 3b08d01b0ab5 and adfe50279922
+        alternatively, use --config merge.preferancestor=0f6b37dbe527
+  resolving manifests
+  merging f1
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
+  [1]
+
   $ cd ..