[PATCH 1 of 4 V2] destutil: explicitly remove descendants from destmerge candidates

Pierre-Yves David pierre-yves.david at ens-lyon.org
Sun Feb 14 15:38:13 UTC 2016


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at fb.com>
# Date 1454951526 -3600
#      Mon Feb 08 18:12:06 2016 +0100
# Node ID 0ffdd65816fcde6f970e60830fad8aa0bc67b970
# Parent  2c83ae6c59cbd509633475c3117c15de3595eff7
# EXP-Topic destination
# Available At http://hg.netv6.net/marmoute-wip/mercurial/
#              hg pull http://hg.netv6.net/marmoute-wip/mercurial/ -r 0ffdd65816fc
destutil: explicitly remove descendants from destmerge candidates

While 'hg merge' will refuse to pick a default destination if the working copy
is not on a head, this will be a common and valid case for rebase. In this
case, we will need to exclude from the candidate destination all descendants
from the rebased set.

We make a step forward in that direction by removing parents of the working
copy from the candidate destinations instead of manually filtering the working
copy parent at the end of the process. This will make the extra step of
filtering descendant much simpler in a future changeset.

diff --git a/mercurial/destutil.py b/mercurial/destutil.py
--- a/mercurial/destutil.py
+++ b/mercurial/destutil.py
@@ -210,45 +210,46 @@ def _destmergebranch(repo, action='merge
     """find merge destination based on branch heads"""
     node = None
     parent = repo.dirstate.p1()
     branch = repo.dirstate.branch()
     bheads = repo.branchheads(branch)
-    nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
 
     if parent not in bheads:
         # Case A: working copy if not on a head.
         #
         # This is probably a user mistake We bailout pointing at 'hg update'
         if len(repo.heads()) <= 1:
             msg, hint = msgdestmerge['nootherheadsbehind'][action]
         else:
             msg, hint = msgdestmerge['notatheads'][action]
         raise error.Abort(msg, hint=hint)
-    elif len(nbhs) > 2:
-        # Case B: There is more than 2 anonymous heads
+    # remove current head from the set
+    bheads = [bh for bh in bheads if bh != parent]
+    # filters out bookmarked heads
+    nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
+    if len(nbhs) > 1:
+        # Case B: There is more than 1 other anonymous heads
         #
         # This means that there will be more than 1 candidate. This is
         # ambiguous. We abort asking the user to pick as explicit destination
         # instead.
         msg, hint = msgdestmerge['toomanyheads'][action]
-        msg %= (branch, len(bheads))
+        msg %= (branch, len(bheads) + 1)
         raise error.Abort(msg, hint=hint)
-    elif len(nbhs) <= 1:
-        # Case B: There is no other anonymous head that the one we are one
+    elif not nbhs:
+        # Case B: There is no other anonymous heads
         #
         # This means that there is no natural candidate to merge with.
         # We abort, with various messages for various cases.
-        if len(bheads) > 1:
+        if bheads:
             msg, hint = msgdestmerge['bookmarkedheads'][action]
         elif len(repo.heads()) > 1:
             msg, hint = msgdestmerge['nootherbranchheads'][action]
             msg %= branch
         else:
             msg, hint = msgdestmerge['nootherheads'][action]
         raise error.Abort(msg, hint=hint)
-    elif parent == nbhs[0]:
-        node = nbhs[-1]
     else:
         node = nbhs[0]
     assert node is not None
     return node
 


More information about the Mercurial-devel mailing list