# HG changeset patch # User Pierre-Yves David # Date 1406301234 -7200 # Node ID 1d8ba82440012bee2ac85b8f590156f437da3ffc # Parent deba3a063c6378bf89194ec06f1e17d40610d879 push: put phase in the same bundle2 than changegroup and obsmarkers Note that the usual phase push from core will be performed in all case. But the discovery should find already in sync phase at that time. The old ways sync will be properly skipped when this logic is introduced into core. diff -r deba3a063c63 -r 1d8ba8244001 README --- a/README Fri Jul 25 16:54:08 2014 +0200 +++ b/README Fri Jul 25 17:13:54 2014 +0200 @@ -62,8 +62,8 @@ - amend: add -D/--current-date option - amend: add -U/--current-user option - evolve: add a --tool option -- push obsmarkers in the same transaction than changesets (when using hg >= 3.1 - and bundle2-exp is enabled) +- push obsmarkers and phases in the same transaction than changesets + (when using hg >= 3.1 and bundle2-exp is enabled) 4.0.0 -- 2014-06-03 diff -r deba3a063c63 -r 1d8ba8244001 hgext/evolve.py --- 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)