destmerge: improve topic head computation and handling
authorPierre-Yves David <pierre-yves.david@ens-lyon.org>
Mon, 15 Aug 2016 05:25:53 +0200
changeset 1983 4864ddc4c6d9
parent 1982 d87fc4f749e6
child 1984 2a07df823588
destmerge: improve topic head computation and handling This rework get use two benefits: - heads are now computed on a "stabilized" state, - heads above the 'source' are now properly cleaned up,
hgext3rd/topic/destination.py
--- a/hgext3rd/topic/destination.py	Mon Aug 15 05:15:19 2016 +0200
+++ b/hgext3rd/topic/destination.py	Mon Aug 15 05:25:53 2016 +0200
@@ -8,6 +8,7 @@
     extensions,
     util,
 )
+from .evolvebits import builddependencies
 
 def _destmergebranch(orig, repo, action='merge', sourceset=None,
                      onheadcheck=True, destspace=None):
@@ -15,11 +16,21 @@
     p1 = repo['.']
     top = p1.topic()
     if top:
-        heads = repo.revs('heads(topic(.)::topic(.))')
+        revs = repo.revs('topic(%s) - obsolete()', top)
+        deps, rdeps = builddependencies(repo, revs)
+        heads = [r for r in revs if not rdeps[r]]
         if onheadcheck and p1.rev() not in heads:
             raise error.Abort(_("not at topic head, update or explicit"))
-        elif 1 == len(heads):
-            # should look at all branch involved but... later
+
+        # prune heads above the source
+        otherheads = set(heads)
+        pool = set([p1.rev()])
+        while pool:
+            current = pool.pop()
+            otherheads.discard(current)
+            pool.update(rdeps[current])
+        if not otherheads:
+            # nothing to do at the topic level
             bhead = ngtip(repo, p1.branch(), all=True)
             if not bhead:
                 raise error.NoMergeDestAbort(_("nothing to merge"))
@@ -31,20 +42,12 @@
                 hint = _("run 'hg heads .' to see heads")
                 raise error.ManyMergeDestAbort(msg % (p1.branch(), len(bhead)),
                                                hint=hint)
-        elif 2 == len(heads):
-            heads = [r for r in heads if r != p1.rev()]
-            # XXX: bla bla bla bla bla
-            if 1 < len(heads):
-                raise error.Abort(_('working directory not at a head revision'),
-                                  hint=_("use 'hg update' or merge with an "
-                                         "explicit revision"))
-            return heads[0]
-        elif 2 < len(heads):
+        elif len(otherheads) == 1:
+            return otherheads.pop()
+        else:
             msg = _("topic '%s' has %d heads "
                     "- please merge with an explicit rev") % (top, len(heads))
             raise error.ManyMergeDestAbort(msg)
-        else:
-            assert False # that's impossible
     if len(getattr(orig, 'func_defaults', ())) == 3: # version hg-3.7
         return orig(repo, action, sourceset, onheadcheck)
     if 3 < len(getattr(orig, 'func_defaults', ())): # version hg-3.8 and above