diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt --- a/mercurial/help/config.txt +++ b/mercurial/help/config.txt @@ -1345,14 +1345,26 @@ Controls generic server settings. Whether to allow clients to push and pull using the legacy bundle1 exchange format. (default: True) +``bundle1gd`` + Like ``bundle1` but only used if the repository is using the + *generaldelta* storage format. (default: True) + ``bundle1.push`` Whether to allow clients to push using the legacy bundle1 exchange format. (default: True) +``bundle1gd.push`` + Like ``bundle1.push` but only used if the repository is using the + *generaldelta* storage format. (default: True) + ``bundle1.pull`` Whether to allow clients to pull using the legacy bundle1 exchange format. (default: True) +``bundle1gd.pull`` + Like ``bundle1.pull` but only used if the repository is using the + *generaldelta* storage format. (default: True) + Large repositories using the *generaldelta* storage format should consider setting this option because converting *generaldelta* repositories to the exchange format required by the bundle1 data diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -491,12 +491,33 @@ def options(cmd, keys, others): % (cmd, ",".join(others))) return opts -def bundle1allowed(ui, action): - """Whether a bundle1 operation is allowed from the server.""" +def bundle1allowed(repo, action): + """Whether a bundle1 operation is allowed from the server. + + Priority is: + + 1. server.bundle1gd. (if generaldelta active) + 2. server.bundle1. + 3. server.bundle1gd (if generaldelta active) + 4. server.bundle1 + """ + ui = repo.ui + gd = 'generaldelta' in repo.requirements + + if gd: + v = ui.configbool('server', 'bundle1gd.%s' % action, None) + if v is not None: + return v + v = ui.configbool('server', 'bundle1.%s' % action, None) if v is not None: return v + if gd: + v = ui.configbool('server', 'bundle1gd', None) + if v is not None: + return v + return ui.configbool('server', 'bundle1', True) # list of commands @@ -665,7 +686,7 @@ def getbundle(repo, proto, others): raise KeyError('unknown getbundle option type %s' % keytype) - if not bundle1allowed(repo.ui, 'pull'): + if not bundle1allowed(repo, 'pull'): if not exchange.bundle2requested(opts.get('bundlecaps')): return ooberror(bundle2required) @@ -781,7 +802,7 @@ def unbundle(repo, proto, heads): fp.seek(0) gen = exchange.readbundle(repo.ui, fp, None) if (isinstance(gen, changegroupmod.cg1unpacker) - and not bundle1allowed(repo.ui, 'push')): + and not bundle1allowed(repo, 'push')): return ooberror(bundle2required) r = exchange.unbundle(repo, gen, their_heads, 'serve', 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 @@ -977,6 +977,51 @@ Servers can disable bundle1 for clone/pu (see https://www.mercurial-scm.org/wiki/IncompatibleClient) [255] $ killdaemons.py + $ cd .. + +bundle1 can still pull non-generaldelta repos when generaldelta bundle1 disabled + + $ hg --config format.usegeneraldelta=false init notgdserver + $ cd notgdserver + $ cat > .hg/hgrc << EOF + > [server] + > bundle1gd.pull = false + > EOF + + $ touch foo + $ hg -q commit -A -m initial + $ hg serve -p $HGPORT -d --pid-file=hg.pid + $ cat hg.pid >> $DAEMON_PIDS + + $ hg --config experimental.bundle2-exp=false clone http://localhost:$HGPORT/ not-bundle2-1 + requesting all changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + updating to branch default + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + + $ killdaemons.py + $ cd ../bundle2onlyserver + +bundle1 pull can be disabled for generaldelta repos only + + $ cat > .hg/hgrc << EOF + > [server] + > bundle1gd.pull = false + > EOF + + $ hg serve -p $HGPORT -d --pid-file=hg.pid + $ cat hg.pid >> $DAEMON_PIDS + $ hg --config experimental.bundle2-exp=false clone http://localhost:$HGPORT/ not-bundle2 + requesting all changes + abort: remote error: + incompatible Mercurial client; bundle2 required + (see https://www.mercurial-scm.org/wiki/IncompatibleClient) + [255] + + $ killdaemons.py Verify the global server.bundle1 option works @@ -994,6 +1039,42 @@ Verify the global server.bundle1 option [255] $ killdaemons.py + $ cat > .hg/hgrc << EOF + > [server] + > bundle1gd = false + > EOF + $ hg serve -p $HGPORT -d --pid-file=hg.pid + $ cat hg.pid >> $DAEMON_PIDS + + $ hg --config experimental.bundle2-exp=false clone http://localhost:$HGPORT/ not-bundle2 + requesting all changes + abort: remote error: + incompatible Mercurial client; bundle2 required + (see https://www.mercurial-scm.org/wiki/IncompatibleClient) + [255] + + $ killdaemons.py + + $ cd ../notgdserver + $ cat > .hg/hgrc << EOF + > [server] + > bundle1gd = false + > EOF + $ hg serve -p $HGPORT -d --pid-file=hg.pid + $ cat hg.pid >> $DAEMON_PIDS + + $ hg --config experimental.bundle2-exp=false clone http://localhost:$HGPORT/ not-bundle2-2 + requesting all changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + updating to branch default + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + + $ killdaemons.py + $ cd ../bundle2onlyserver + Verify bundle1 pushes can be disabled $ cat > .hg/hgrc << EOF