[PATCH 6 of 6 clone bundles] clonebundles: advertise clone bundles feature to clients
Gregory Szorc
gregory.szorc at gmail.com
Wed Oct 14 13:07:58 CDT 2015
# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1444845953 25200
# Wed Oct 14 11:05:53 2015 -0700
# Node ID 2aaae4e1134db787e6fdc41829b17451750a2d4d
# Parent 69474173bfb98339226a29c0ba132adb7619626a
clonebundles: advertise clone bundles feature to clients
Server operators that have enabled clone bundles probably want clients
to use it. This patch introduces a feature that will insert a bundle2
"output" part that advertises the existence of the clone bundles
feature to clients that aren't using it.
The server uses the "cbattempted" argument to "getbundle" to determine
whether a client supports clone bundles and to avoid sending the message
to clients that failed the clone bundle for whatever reason.
diff --git a/hgext/clonebundles.py b/hgext/clonebundles.py
--- a/hgext/clonebundles.py
+++ b/hgext/clonebundles.py
@@ -63,9 +63,12 @@ REQUIRESNI
Value should be "true".
"""
+from mercurial.i18n import _
+from mercurial.node import nullid
from mercurial import (
+ exchange,
extensions,
wireproto,
)
@@ -93,6 +96,45 @@ def bundles(repo, proto):
the closest data center given the client's IP address.
"""
return repo.opener.tryread('clonebundles.manifest')
+ at exchange.getbundle2partsgenerator('clonebundlesadvertise', 0)
+def advertiseclonebundlespart(bundler, repo, source, bundlecaps=None,
+ b2caps=None, heads=None, common=None,
+ cbattempted=None, **kwargs):
+ """Inserts an output part to advertise clone bundles availability."""
+ # Allow server operators to disable this behavior.
+ # # experimental config: ui.clonebundleadvertise
+ if not repo.ui.configbool('ui', 'clonebundleadvertise', True):
+ return
+
+ # Only advertise if a manifest is present.
+ if not repo.opener.exists('clonebundles.manifest'):
+ return
+
+ # And when changegroup data is requested.
+ if not kwargs.get('cg', True):
+ return
+
+ # And when the client supports clone bundles.
+ if cbattempted is None:
+ return
+
+ # And when the client didn't attempt a clone bundle as part of this pull.
+ if cbattempted:
+ return
+
+ # And when a full clone is requested.
+ # Note: client should not send "cbattempted" for regular pulls. This check
+ # is defense in depth.
+ if common and common != [nullid]:
+ return
+
+ msg = _('this server supports the experimental "clone bundles" feature '
+ 'that should enable faster and more reliable cloning\n'
+ 'help test it by setting the "experimental.clonebundles" config '
+ 'flag to "true"')
+
+ bundler.newpart('output', data=msg)
+
def extsetup(ui):
extensions.wrapfunction(wireproto, '_capabilities', capabilities)
diff --git a/tests/test-clonebundles.t b/tests/test-clonebundles.t
--- a/tests/test-clonebundles.t
+++ b/tests/test-clonebundles.t
@@ -63,8 +63,19 @@ Empty manifest file results in retrieval
adding manifests
adding file changes
added 2 changesets with 2 changes to 2 files
+Server advertises presence of feature to client requesting full clone
+
+ $ hg --config experimental.clonebundles=false clone -U http://localhost:$HGPORT advertise-on-clone
+ requesting all changes
+ remote: this server supports the experimental "clone bundles" feature that should enable faster and more reliable cloning
+ remote: help test it by setting the "experimental.clonebundles" config flag to "true"
+ adding changesets
+ adding manifests
+ adding file changes
+ added 2 changesets with 2 changes to 2 files
+
Manifest file with invalid URL aborts
$ echo 'http://does.not.exist/bundle.hg' > server/.hg/clonebundles.manifest
$ hg clone http://localhost:$HGPORT 404-url
More information about the Mercurial-devel
mailing list