hgext/evolve.py
changeset 1007 1d8ba8244001
parent 1006 deba3a063c63
child 1008 a010ba5a0ffb
--- a/hgext/evolve.py	Fri Jul 25 16:54:08 2014 +0200
+++ b/hgext/evolve.py	Fri Jul 25 17:13:54 2014 +0200
@@ -58,6 +58,7 @@
 from mercurial import node
 from mercurial import phases
 from mercurial import patch
+from mercurial import pushkey
 from mercurial import revset
 from mercurial import scmutil
 from mercurial import templatekw
@@ -2320,7 +2321,64 @@
 
 bundle2partsgenerators = getattr(exchange, 'bundle2partsgenerators', None)
 
+
 if bundle2partsgenerators is not None:
+
+    def _pushb2phases(pushop, bundler):
+        """adds phases update to the main bundle2 push"""
+        outgoing = pushop.outgoing
+        unfi = pushop.repo.unfiltered()
+        remotephases = pushop.remote.listkeys('phases')
+        publishing = remotephases.get('publishing', False)
+        ana = phases.analyzeremotephases(pushop.repo,
+                                         outgoing.commonheads,
+                                         remotephases)
+        pheads, droots = ana
+        revset = 'heads((%ln::%ln))'
+        if not publishing:
+            revset += ' and public()'
+        # Get the list of all revs draft on remote by public here.
+        # XXX Beware that revset break if droots is not strictly
+        # XXX root we may want to ensure it is but it is costly
+        fallback = list(unfi.set(revset, droots, outgoing.commonheads))
+        if not outgoing.missing:
+            future = fallback
+        else:
+            # adds changeset we are going to push as draft
+            #
+            # should not be necessary for pushblishing server, but because of
+            # an issue fixed in xxxxx we have to do it anyway.
+            fdroots = list(unfi.set('roots(%ln  + %ln::)', outgoing.missing, droots))
+            fdroots = [f.node() for f in fdroots]
+            future = list(unfi.set(revset, fdroots, outgoing.missingheads))
+
+        b2caps = bundle2.bundle2caps(pushop.remote)
+        if 'b2x:pushkey' not in b2caps:
+            return
+        pushop.stepsdone.add('phases')
+        part2node = []
+        enc = pushkey.encode
+        for newremotehead in future:
+            part = bundler.newpart('b2x:pushkey')
+            part.addparam('namespace', enc('phases'))
+            part.addparam('key', enc(newremotehead.hex()))
+            part.addparam('old', enc(str(phases.draft)))
+            part.addparam('new', enc(str(phases.public)))
+            part2node.append((part.id, newremotehead))
+        def handlereply(op):
+            for partid, pnode in part2node:
+                partrep = op.records.getreplies(partid)
+                results = partrep['pushkey']
+                assert len(results) <= 1
+                msg = None
+                if not results:
+                    msg = _('server ignored update of %s to public!\n') % pnode
+                elif not int(results[0]['return']):
+                    msg = _('updating %s to public failed!\n') % pnode
+                if msg is not None:
+                    pushop.ui.warn(msg)
+        return handlereply
+
     def _pushb2obsmarker(pushop, bundler):
         """adds obsmarker to the main bundle2 push"""
         repo = pushop.repo
@@ -2347,6 +2405,7 @@
                 repo.ui.progress('OBSEXC', None)
                 repo.ui.status("OBSEXC: DONE\n")
             return callback
+    bundle2partsgenerators.append(_pushb2phases)
     bundle2partsgenerators.append(_pushb2obsmarker)