Mercurial > hg
changeset 21662:09f19e09f1b4
push: use bundle2 to push phases when available
We now use a bundle2 container to push all phase updates at the same time. This
is a significant step forward, even if further refactoring is needed to unify
phase push with the changeset push.
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Tue, 27 May 2014 16:33:06 -0700 |
parents | 2f52a16f2bee |
children | 8d9449eaaeff |
files | mercurial/exchange.py |
diffstat | 1 files changed, 48 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/exchange.py Thu May 29 15:22:58 2014 -0700 +++ b/mercurial/exchange.py Tue May 27 16:33:06 2014 -0700 @@ -359,16 +359,54 @@ # 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 - outdated = unfi.set('heads((%ln::%ln) and public())', - droots, cheads) - for newremotehead in outdated: - r = pushop.remote.pushkey('phases', - newremotehead.hex(), - str(phases.draft), - str(phases.public)) - if not r: - pushop.ui.warn(_('updating %s to public failed!\n') - % newremotehead) + outdated = unfi.set('heads((%ln::%ln) and public())', + droots, cheads) + + 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 + bundler = bundle2.bundle20(pushop.ui, b2caps) + capsblob = bundle2.encodecaps(pushop.repo.bundle2caps) + bundler.newpart('b2x:replycaps', data=capsblob) + part2node = [] + enc = pushkey.encode + for newremotehead in outdated: + 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)) + stream = util.chunkbuffer(bundler.getchunks()) + try: + reply = pushop.remote.unbundle(stream, ['force'], 'push') + op = bundle2.processbundle(pushop.repo, reply) + except error.BundleValueError, exc: + raise util.Abort('missing support for %s' % exc) + 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) + + else: + # fallback to independant pushkey command + for newremotehead in outdated: + r = pushop.remote.pushkey('phases', + newremotehead.hex(), + str(phases.draft), + str(phases.public)) + if not r: + pushop.ui.warn(_('updating %s to public failed!\n') + % newremotehead) def _localphasemove(pushop, nodes, phase=phases.public): """move <nodes> to <phase> in the local source repo"""