Patchwork [7,of,7] push: include phase push in the unified bundle2 push

login
register
mail settings
Submitter Pierre-Yves David
Date Aug. 4, 2014, 10:32 p.m.
Message ID <eea31cd4085513ce27f4.1407191529@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/5255/
State Accepted
Headers show

Comments

Pierre-Yves David - Aug. 4, 2014, 10:32 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1404248897 -7200
#      Tue Jul 01 23:08:17 2014 +0200
# Node ID eea31cd4085513ce27f4f22f632aa292a11264b9
# Parent  8ebab0fd80c7de4652389b42568b160da9bfb7f1
push: include phase push in the unified bundle2 push

Phase push is now included in the same bundle2 push than changesets. We use
multiple pushkey parts to transmit the information. Note that phase moves are
still not part of the repository "transaction".
Matt Mackall - Aug. 5, 2014, 8:56 p.m.
On Mon, 2014-08-04 at 15:32 -0700, pierre-yves.david@ens-lyon.org wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david@fb.com>
> # Date 1404248897 -7200
> #      Tue Jul 01 23:08:17 2014 +0200
> # Node ID eea31cd4085513ce27f4f22f632aa292a11264b9
> # Parent  8ebab0fd80c7de4652389b42568b160da9bfb7f1
> push: include phase push in the unified bundle2 push

These are queued for default, thanks.

Patch

diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -365,10 +365,41 @@  def _pushb2ctx(pushop, bundler):
         cgreplies = op.records.getreplies(cgpart.id)
         assert len(cgreplies['changegroup']) == 1
         pushop.ret = cgreplies['changegroup'][0]['return']
     return handlereply
 
+@b2partsgenerator('phase')
+def _pushb2phases(pushop, bundler):
+    """handle phase push through bundle2"""
+    if 'phases' in pushop.stepsdone:
+        return
+    b2caps = bundle2.bundle2caps(pushop.remote)
+    if not 'b2x:pushkey' in b2caps:
+        return
+    pushop.stepsdone.add('phases')
+    part2node = []
+    enc = pushkey.encode
+    for newremotehead in pushop.outdatedphases:
+        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, node 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') % node
+            elif not int(results[0]['return']):
+                msg = _('updating %s to public failed!\n') % node
+            if msg is not None:
+                pushop.ui.warn(msg)
+    return handlereply
 
 def _pushbundle2(pushop):
     """push data to the remote using bundle2
 
     The only currently supported type of data is changegroup but this will
@@ -479,17 +510,21 @@  def _pushsyncphase(pushop):
             _localphasemove(pushop, pheads)
             _localphasemove(pushop, cheads, phases.draft)
         ### Apply local phase on remote
 
         if pushop.ret:
+            if 'phases' in pushop.stepsdone:
+                # phase already pushed though bundle2
+                return
             outdated = pushop.outdatedphases
         else:
             outdated = pushop.fallbackoutdatedphases
 
+        pushop.stepsdone.add('phases')
+
         # filter heads already turned public by the push
         outdated = [c for c in outdated if c.node() not in pheads]
-
         b2caps = bundle2.bundle2caps(pushop.remote)
         if 'b2x:pushkey' in b2caps:
             # server supports bundle2, let's do a batched push through it
             #
             # This will eventually be unified with the changesets bundle2 push