[PATCH 6 of 7] push: perform phases discovery before the push

pierre-yves.david at ens-lyon.org pierre-yves.david at ens-lyon.org
Mon Aug 4 17:32:08 CDT 2014


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at fb.com>
# Date 1406773607 25200
#      Wed Jul 30 19:26:47 2014 -0700
# Node ID 8ebab0fd80c7de4652389b42568b160da9bfb7f1
# Parent  52603c1d28853d4332a0c9821939047fbd387b6d
push: perform phases discovery before the push

This will allow to includes phase information in the same bundle2 as the
changesets.

diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -75,10 +75,14 @@ class pushoperation(object):
         self.outgoing = None
         # all remote heads before the push
         self.remoteheads = None
         # testable as a boolean indicating if any nodes are missing locally.
         self.incoming = None
+        # phases changes that must be pushed along side the changesets
+        self.outdatedphases = None
+        # phases changes that must be pushed if changeset push fails
+        self.fallbackoutdatedphases = None
 
     @util.propertycache
     def futureheads(self):
         """future remote heads if the changeset push succeed"""
         return self.outgoing.missingheads
@@ -235,10 +239,46 @@ def _pushdiscoverychangeset(pushop):
                    commoninc=commoninc, force=pushop.force)
     pushop.outgoing = outgoing
     pushop.remoteheads = remoteheads
     pushop.incoming = inc
 
+ at pushdiscovery('phase')
+def _pushdiscoveryphase(pushop):
+    """discover the phase that needs to be pushed
+
+    (computed for both success and failure case for changesets push)"""
+    outgoing = pushop.outgoing
+    unfi = pushop.repo.unfiltered()
+    remotephases = pushop.remote.listkeys('phases')
+    publishing = remotephases.get('publishing', False)
+    ana = phases.analyzeremotephases(pushop.repo,
+                                     pushop.fallbackheads,
+                                     remotephases)
+    pheads, droots = ana
+    extracond = ''
+    if not publishing:
+        extracond = ' and public()'
+    revset = 'heads((%%ln::%%ln) %s)' % extracond
+    # 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, pushop.fallbackheads))
+    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, pushop.futureheads))
+    pushop.outdatedphases = future
+    pushop.fallbackoutdatedphases = fallback
+
+
 def _pushcheckoutgoing(pushop):
     outgoing = pushop.outgoing
     unfi = pushop.repo.unfiltered()
     if not outgoing.missing:
         # nothing to push
@@ -406,11 +446,10 @@ def _pushchangeset(pushop):
         # change
         pushop.ret = pushop.remote.addchangegroup(cg, 'push', pushop.repo.url())
 
 def _pushsyncphase(pushop):
     """synchronise phase information locally and remotely"""
-    unfi = pushop.repo.unfiltered()
     cheads = pushop.commonheads
     # even when we don't push, exchanging phase data is useful
     remotephases = pushop.remote.listkeys('phases')
     if (pushop.ui.configbool('ui', '_usedassubrepo', False)
         and remotephases    # server supports phases
@@ -439,15 +478,17 @@ def _pushsyncphase(pushop):
         else: # publish = False
             _localphasemove(pushop, pheads)
             _localphasemove(pushop, cheads, phases.draft)
         ### Apply local phase on remote
 
-        # 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)
+        if pushop.ret:
+            outdated = pushop.outdatedphases
+        else:
+            outdated = pushop.fallbackoutdatedphases
+
+        # filter heads already turned public by the push
+        outdated = [c for c in outdated if c.node() not in pheads]
 
         b2caps = bundle2.bundle2caps(pushop.remote)
         if 'b2x:pushkey' in b2caps:
             # server supports bundle2, let's do a batched push through it
             #
diff --git a/tests/test-acl.t b/tests/test-acl.t
--- a/tests/test-acl.t
+++ b/tests/test-acl.t
@@ -80,10 +80,11 @@ Extension disabled for lack of a hook
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -138,10 +139,11 @@ Extension disabled for lack of acl.sourc
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   invalid branchheads cache (served): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
@@ -200,10 +202,11 @@ No [acl.allow]/[acl.deny]
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   invalid branchheads cache (served): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
@@ -272,10 +275,11 @@ Empty [acl.allow]
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   invalid branchheads cache (served): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
@@ -339,10 +343,11 @@ fred is allowed inside foo/
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   invalid branchheads cache (served): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
@@ -411,10 +416,11 @@ Empty [acl.deny]
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   invalid branchheads cache (served): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
@@ -480,10 +486,11 @@ fred is allowed inside foo/, but not foo
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   invalid branchheads cache (served): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
@@ -554,10 +561,11 @@ fred is allowed inside foo/, but not foo
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   invalid branchheads cache (served): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
@@ -625,10 +633,11 @@ fred is allowed inside foo/, but not foo
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   invalid branchheads cache (served): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
@@ -698,10 +707,11 @@ barney is allowed everywhere
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   invalid branchheads cache (served): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
@@ -777,10 +787,11 @@ wilma can change files with a .txt exten
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   invalid branchheads cache (served): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
@@ -857,10 +868,11 @@ file specified by acl.config does not ex
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   invalid branchheads cache (served): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
@@ -932,10 +944,11 @@ betty is allowed inside foo/ by a acl.co
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   invalid branchheads cache (served): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
@@ -1018,10 +1031,11 @@ acl.config can set only [acl.allow]/[acl
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   invalid branchheads cache (served): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
@@ -1098,10 +1112,11 @@ fred is always allowed
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   invalid branchheads cache (served): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
@@ -1174,10 +1189,11 @@ no one is allowed inside foo/Bar/
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   invalid branchheads cache (served): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
@@ -1250,10 +1266,11 @@ OS-level groups
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   invalid branchheads cache (served): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
@@ -1327,10 +1344,11 @@ OS-level groups
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   invalid branchheads cache (served): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
@@ -1442,10 +1460,11 @@ No branch acls specified
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   listing keys for "bookmarks"
   4 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -1525,10 +1544,11 @@ Branch acl deny test
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   listing keys for "bookmarks"
   4 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -1604,10 +1624,11 @@ Branch acl empty allow test
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   listing keys for "bookmarks"
   4 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -1679,10 +1700,11 @@ Branch acl allow other
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   listing keys for "bookmarks"
   4 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -1748,10 +1770,11 @@ Branch acl allow other
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   listing keys for "bookmarks"
   4 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -1836,10 +1859,11 @@ push foobar into the remote
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   listing keys for "bookmarks"
   4 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -1923,10 +1947,11 @@ Branch acl conflicting deny
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   listing keys for "bookmarks"
   4 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -1997,10 +2022,11 @@ User 'astro' must not be denied
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   listing keys for "bookmarks"
   4 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -2078,10 +2104,11 @@ Non-astro users must be denied
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  listing keys for "phases"
   listing keys for "bookmarks"
   4 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
diff --git a/tests/test-hook.t b/tests/test-hook.t
--- a/tests/test-hook.t
+++ b/tests/test-hook.t
@@ -208,10 +208,11 @@ test that prepushkey can prevent incomin
   $ cd ../b
   $ hg bookmark -r null baz
   $ hg push -B baz ../a
   pushing to ../a
   searching for changes
+  listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
   no changes found
   listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
   listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
   listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
   exporting bookmark baz
diff --git a/tests/test-http.t b/tests/test-http.t
--- a/tests/test-http.t
+++ b/tests/test-http.t
@@ -259,13 +259,14 @@ test http authentication
   "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
   "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
   "GET /?cmd=listkeys HTTP/1.1" 403 - x-hgarg-1:namespace=namespaces
   "GET /?cmd=capabilities HTTP/1.1" 200 -
   "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D7f4e523d01f2cc3765ac8934da3d14db775ff872
+  "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=phases
+  "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases
   "GET /?cmd=branchmap HTTP/1.1" 200 -
   "GET /?cmd=branchmap HTTP/1.1" 200 -
-  "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=bookmarks
   "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
   "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=686173686564+5eb5abfefeea63c80dd7553bcc3783f37e0c5524
   "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases
   "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
 
diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t
--- a/tests/test-obsolete.t
+++ b/tests/test-obsolete.t
@@ -315,10 +315,11 @@ Try to push markers
 Check obsolete keys are exchanged only if source has an obsolete store
 
   $ hg init empty
   $ hg --config extensions.debugkeys=debugkeys.py -R empty push tmpd
   pushing to tmpd
+  listkeys phases
   no changes found
   listkeys phases
   listkeys bookmarks
   [1]
 
diff --git a/tests/test-push-warn.t b/tests/test-push-warn.t
--- a/tests/test-push-warn.t
+++ b/tests/test-push-warn.t
@@ -33,10 +33,11 @@
   searching for changes
   taking quick initial sample
   searching: 2 queries
   query 2; still undecided: 1, sample size is: 1
   2 total queries
+  listing keys for "phases"
   listing keys for "bookmarks"
   remote has heads on branch 'default' that are not known locally: 1c9246a22a0a
   new remote heads on branch 'default':
    1e108cc5548c
   abort: push creates new remote head 1e108cc5548c!


More information about the Mercurial-devel mailing list