Patchwork [5,of,8] phase: introduce a new 'check:phases' part

login
register
mail settings
Submitter Boris Feld
Date Oct. 16, 2017, 1:41 p.m.
Message ID <3e12cfeb7b0177e2efdd.1508161272@FB>
Download mbox | patch
Permalink /patch/24982/
State Superseded
Headers show

Comments

Boris Feld - Oct. 16, 2017, 1:41 p.m.
# HG changeset patch
# User Boris Feld <boris.feld@octobus.net>
# Date 1507698782 -7200
#      Wed Oct 11 07:13:02 2017 +0200
# Node ID 3e12cfeb7b0177e2efdd39de00dc7f03daaaa944
# Parent  c581583a2c085662c9a59f55f2483a2c748eb573
# EXP-Topic b2.phases.push
# Available At https://bitbucket.org/octobus/mercurial-devel/
#              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 3e12cfeb7b01
phase: introduce a new 'check:phases' part

This part check check 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.

Patch

diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -157,6 +157,7 @@ 
 from . import (
     changegroup,
     error,
+    node as nodemod,
     obsolete,
     phases,
     pushkey,
@@ -1749,6 +1750,26 @@ 
             raise error.PushRaced('repository changed while pushing - '
                                   'please try again')
 
+@parthandler('check:phases')
+def handlecheckphases(op, inpart):
+    """check that phase of the repository did not changed
+
+    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"""