diff --git a/mercurial/exchange.py b/mercurial/exchange.py --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -77,6 +77,10 @@ class pushoperation(object): 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): @@ -237,6 +241,41 @@ def _pushdiscoverychangeset(pushop): pushop.remoteheads = remoteheads pushop.incoming = inc +@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() @@ -408,7 +447,6 @@ def _pushchangeset(pushop): 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') @@ -441,11 +479,13 @@ def _pushsyncphase(pushop): _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: diff --git a/tests/test-acl.t b/tests/test-acl.t --- a/tests/test-acl.t +++ b/tests/test-acl.t @@ -82,6 +82,7 @@ Extension disabled for lack of a hook 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: @@ -140,6 +141,7 @@ Extension disabled for lack of acl.sourc 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 @@ -202,6 +204,7 @@ No [acl.allow]/[acl.deny] 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 @@ -274,6 +277,7 @@ Empty [acl.allow] 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 @@ -341,6 +345,7 @@ fred is allowed inside foo/ 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 @@ -413,6 +418,7 @@ Empty [acl.deny] 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 @@ -482,6 +488,7 @@ fred is allowed inside foo/, but not foo 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 @@ -556,6 +563,7 @@ fred is allowed inside foo/, but not foo 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 @@ -627,6 +635,7 @@ fred is allowed inside foo/, but not foo 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 @@ -700,6 +709,7 @@ barney is allowed everywhere 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 @@ -779,6 +789,7 @@ wilma can change files with a .txt exten 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 @@ -859,6 +870,7 @@ file specified by acl.config does not ex 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 @@ -934,6 +946,7 @@ betty is allowed inside foo/ by a acl.co 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 @@ -1020,6 +1033,7 @@ acl.config can set only [acl.allow]/[acl 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 @@ -1100,6 +1114,7 @@ fred is always allowed 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 @@ -1176,6 +1191,7 @@ no one is allowed inside foo/Bar/ 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 @@ -1252,6 +1268,7 @@ OS-level groups 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 @@ -1329,6 +1346,7 @@ OS-level groups 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 @@ -1444,6 +1462,7 @@ No branch acls specified 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: @@ -1527,6 +1546,7 @@ Branch acl deny test 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: @@ -1606,6 +1626,7 @@ Branch acl empty allow test 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: @@ -1681,6 +1702,7 @@ Branch acl allow other 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: @@ -1750,6 +1772,7 @@ Branch acl allow other 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: @@ -1838,6 +1861,7 @@ push foobar into the remote 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: @@ -1925,6 +1949,7 @@ Branch acl conflicting deny 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: @@ -1999,6 +2024,7 @@ User 'astro' must not be denied 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: @@ -2080,6 +2106,7 @@ Non-astro users must be denied 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: diff --git a/tests/test-hook.t b/tests/test-hook.t --- a/tests/test-hook.t +++ b/tests/test-hook.t @@ -210,6 +210,7 @@ test that prepushkey can prevent incomin $ 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'} diff --git a/tests/test-http.t b/tests/test-http.t --- a/tests/test-http.t +++ b/tests/test-http.t @@ -261,9 +261,10 @@ test http authentication "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 diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t --- a/tests/test-obsolete.t +++ b/tests/test-obsolete.t @@ -317,6 +317,7 @@ Check obsolete keys are exchanged only i $ 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 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 @@ -35,6 +35,7 @@ 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':