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.
--- a/mercurial/bundle2.py Wed Oct 11 18:39:04 2017 +0200
+++ b/mercurial/bundle2.py Wed Oct 11 07:13:02 2017 +0200
@@ -157,6 +157,7 @@
from . import (
changegroup,
error,
+ node as nodemod,
obsolete,
phases,
pushkey,
@@ -1749,6 +1750,27 @@
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"""