wireproto: avoid exposing pushkey abort for server without evolution
Client with evolution enabled will query the 'obsolete' pushley namespace if no
other way to request obsmarkers have been found. They will do this
unconditionally as long as no other obsolescence related capabilities have been
advertised by the server.
The call is "harmless" since the namespace will be empty if obsmarkers exchange
is disabled. However, since we forbid the use of pushkey for obsmarkers this
lead to unexpected crash report for up to date client talking to a server with
the evolve extensions but exchange disabled.
We fix the issue by serving the expected empty namespace in this case. We keep
forbidding the query if obsmarker exchange is enabled since new client should
have picked another more effective was to fetch the data first.
We also add some tests for this logic.
# Extension which prevent changeset to be turn public by push operation
#
# Copyright 2011 Logilab SA <contact@logilab.fr>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from mercurial import extensions, util
from mercurial import discovery
def checkpublish(orig, repo, remote, outgoing, *args):
# is remote publishing?
publish = True
if 'phases' in remote.listkeys('namespaces'):
remotephases = remote.listkeys('phases')
publish = remotephases.get('publishing', False)
npublish = 0
if publish:
for rev in outgoing.missing:
if repo[rev].phase():
npublish += 1
if npublish:
repo.ui.warn("Push would publish %s changesets" % npublish)
ret = orig(repo, remote, outgoing, *args)
if npublish:
raise util.Abort("Publishing push forbidden",
hint="Use `hg phase -p <rev>` to manually publish them")
return ret
def uisetup(ui):
extensions.wrapfunction(discovery, 'checkheads', checkpublish)