# HG changeset patch # User Boris Feld # Date 2017-10-11 05:13:02 # Node ID a95067b1dca6501b62072020b65809dd47471c2a # Parent eb6375651974065739960398b0192f5ad0b53e7f phase: introduce a new 'check:phases' part This part checks if revisions are still in the same phase as when the bundle was generated. This is similar to what 'check:heads' or 'check:updated-heads' bundle2 part achieves for changesets. We needs seems before we can move away from pushkey usage from phase since pushkey has it own built-in push-race detection. diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py --- a/mercurial/bundle2.py +++ b/mercurial/bundle2.py @@ -157,6 +157,7 @@ from .i18n import _ from . import ( changegroup, error, + node as nodemod, obsolete, phases, pushkey, @@ -1749,6 +1750,27 @@ def handlecheckupdatedheads(op, inpart): raise error.PushRaced('repository changed while pushing - ' 'please try again') +@parthandler('check:phases') +def handlecheckphases(op, inpart): + """check that phase boundaries of the repository did not change + + This is used to detect a push race. + """ + phasetonodes = phases.binarydecode(inpart) + unfi = op.repo.unfiltered() + cl = unfi.changelog + phasecache = unfi._phasecache + msg = ('repository changed while pushing - please try again ' + '(%s is %s expected %s)') + for expectedphase, nodes in enumerate(phasetonodes): + for n in nodes: + actualphase = phasecache.phase(unfi, cl.rev(n)) + if actualphase != expectedphase: + finalmsg = msg % (nodemod.short(n), + phases.phasenames[actualphase], + phases.phasenames[expectedphase]) + raise error.PushRaced(finalmsg) + @parthandler('output') def handleoutput(op, inpart): """forward output captured on the server to the client"""