# HG changeset patch # User Pierre-Yves David # Date 2017-02-10 16:56:59 # Node ID d554e624c5feb084e589f4ed14fe8ae639058396 # Parent 4c8dcb491974d97ea3c773ad1ac5588b2bd5478a bundle1: fix bundle1-denied reporting for push over ssh Changeset b288fb2724bf introduced a config option to have the server deny push using bundle1. The original protocol has not really be design to allow such kind of error reporting so some hack was used. It turned the hack only works on HTTP and that ssh wire peer hangs forever when the same hack is used. After further digging, there is no way to report the error in a unified way. Using 'ooberror' freeze ssh and raising 'Abort' makes HTTP return a HTTP500 without further details. So with sadness we implement a version that dispatch according to the protocol used. We also add a test for pushing over ssh to make sure we won't regress in the future. That test show that the hint is missing, this is another bug fixed in the next changeset. diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -33,9 +33,10 @@ from . import ( urlerr = util.urlerr urlreq = util.urlreq -bundle2required = _( - 'incompatible Mercurial client; bundle2 required\n' - '(see https://www.mercurial-scm.org/wiki/IncompatibleClient)\n') +bundle2requiredmain = _('incompatible Mercurial client; bundle2 required') +bundle2requiredhint = _('see https://www.mercurial-scm.org/wiki/' + 'IncompatibleClient') +bundle2required = '%s\n(%s)\n' % (bundle2requiredmain, bundle2requiredhint) class abstractserverproto(object): """abstract class that summarizes the protocol API @@ -948,7 +949,14 @@ def unbundle(repo, proto, heads): gen = exchange.readbundle(repo.ui, fp, None) if (isinstance(gen, changegroupmod.cg1unpacker) and not bundle1allowed(repo, 'push')): - return ooberror(bundle2required) + if proto.name == 'http': + # need to special case http because stderr do not get to + # the http client on failed push so we need to abuse some + # other error type to make sure the message get to the + # user. + return ooberror(bundle2required) + raise error.Abort(bundle2requiredmain, + hint=bundle2requiredhint) r = exchange.unbundle(repo, gen, their_heads, 'serve', proto._client()) diff --git a/tests/test-bundle2-exchange.t b/tests/test-bundle2-exchange.t --- a/tests/test-bundle2-exchange.t +++ b/tests/test-bundle2-exchange.t @@ -1107,6 +1107,14 @@ Verify bundle1 pushes can be disabled (see https://www.mercurial-scm.org/wiki/IncompatibleClient) [255] +(also check with ssh) + + $ hg --config devel.legacy.exchange=bundle1 push ssh://user@dummy/bundle2onlyserver + pushing to ssh://user@dummy/bundle2onlyserver + searching for changes + remote: abort: incompatible Mercurial client; bundle2 required + [1] + $ hg push pushing to http://localhost:$HGPORT/ searching for changes