hgext3rd/topic/discovery.py
branchstable
changeset 3182 bc09dd507c41
parent 2696 a32afe67e8a6
child 3186 9d9ff55d1bb1
--- a/hgext3rd/topic/discovery.py	Tue Nov 07 14:21:19 2017 +0100
+++ b/hgext3rd/topic/discovery.py	Tue Nov 14 21:05:59 2017 +0100
@@ -1,5 +1,6 @@
 from __future__ import absolute_import
 
+import collections
 import weakref
 
 from mercurial.i18n import _
@@ -31,17 +32,50 @@
 
     publishing = ('phases' not in remote.listkeys('namespaces')
                   or bool(remote.listkeys('phases').get('publishing', False)))
-    if publishing or not remote.capable('topics'):
+    if ((publishing or not remote.capable('topics'))
+            and (pushoparg and not pushop.publish)):
         return orig(*args)
 
+    publishedset = ()
+    remotebranchmap = None
+    origremotebranchmap = remote.branchmap
+    if pushoparg: # < hg-4.4 do not have a --publish flag anyway
+        publishednode = [c.node() for c in pushop.outdatedphases]
+        publishedset = repo.revs('ancestors(%ln + %ln)',
+                                 publishednode,
+                                 pushop.remotephases.publicheads)
+
+        rev = repo.unfiltered().changelog.nodemap.get
+
+        def remotebranchmap():
+            # drop topic information from changeset about to be published
+            result = collections.defaultdict(list)
+            for branch, heads in origremotebranchmap().iteritems():
+                if ':' not in branch:
+                    result[branch].extend(heads)
+                else:
+                    namedbranch = branch.split(':', 1)[0]
+                    for h in heads:
+                        r = rev(h)
+                        if r is not None and r in publishedset:
+                            result[namedbranch].append(h)
+                        else:
+                            result[branch].append(h)
+            for heads in result.itervalues():
+                heads.sort()
+            return result
+
     class repocls(repo.__class__):
         # awful hack to see branch as "branch:topic"
         def __getitem__(self, key):
             ctx = super(repocls, self).__getitem__(key)
             oldbranch = ctx.branch
+            rev = ctx.rev()
 
             def branch():
                 branch = oldbranch()
+                if rev in publishedset:
+                    return branch
                 topic = ctx.topic()
                 if topic:
                     branch = "%s:%s" % (branch, topic)
@@ -56,6 +90,8 @@
 
             def branchinfo(rev):
                 branch, close = changelog.branchinfo(rev)
+                if rev in publishedset:
+                    return branch, close
                 topic = repo[rev].topic()
                 if topic:
                     branch = "%s:%s" % (branch, topic)
@@ -67,6 +103,7 @@
     oldrepocls = repo.__class__
     try:
         repo.__class__ = repocls
+        remote.branchmap = remotebranchmap
         unxx = repo.filtered('unfiltered-topic')
         repo.unfiltered = lambda: unxx
         if pushoparg:
@@ -83,6 +120,7 @@
         if 'unfiltered' in vars(repo):
             del repo.unfiltered
         repo.__class__ = oldrepocls
+        remote.branchmap = origremotebranchmap
 
 def wireprotobranchmap(orig, repo, proto):
     oldrepo = repo.__class__