--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext3rd/pullbundle.py Sun Sep 23 23:53:23 2018 +0200
@@ -0,0 +1,90 @@
+# Extension to provide automatic caching of bundle server for pull
+#
+# Copyright 2018 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
+#
+# 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 (
+ changegroup,
+ exchange,
+ narrowspec,
+)
+
+from mercurial.i18n import _
+
+def uisetup(ui):
+ exchange.getbundle2partsmapping['changegroup'] = _getbundlechangegrouppart
+
+def _getbundlechangegrouppart(bundler, repo, source, bundlecaps=None,
+ b2caps=None, heads=None, common=None, **kwargs):
+ """add a changegroup part to the requested bundle"""
+ if not kwargs.get(r'cg', True):
+ return
+
+ version = '01'
+ cgversions = b2caps.get('changegroup')
+ if cgversions: # 3.1 and 3.2 ship with an empty value
+ cgversions = [v for v in cgversions
+ if v in changegroup.supportedoutgoingversions(repo)]
+ if not cgversions:
+ raise ValueError(_('no common changegroup version'))
+ version = max(cgversions)
+
+ outgoing = exchange._computeoutgoing(repo, heads, common)
+ if not outgoing.missing:
+ return
+
+ if kwargs.get(r'narrow', False):
+ include = sorted(filter(bool, kwargs.get(r'includepats', [])))
+ exclude = sorted(filter(bool, kwargs.get(r'excludepats', [])))
+ filematcher = narrowspec.match(repo.root, include=include,
+ exclude=exclude)
+ else:
+ filematcher = None
+
+ # START OF ALTERED PART
+ makeallcgpart(bundler.newpart, repo, outgoing, version, source, bundlecaps,
+ filematcher, cgversions)
+ # END OF ALTERED PART
+
+ if kwargs.get(r'narrow', False) and (include or exclude):
+ narrowspecpart = bundler.newpart('narrow:spec')
+ if include:
+ narrowspecpart.addparam(
+ 'include', '\n'.join(include), mandatory=True)
+ if exclude:
+ narrowspecpart.addparam(
+ 'exclude', '\n'.join(exclude), mandatory=True)
+
+def makeallcgpart(newpart, repo, outgoing, version, source,
+ bundlecaps, filematcher, cgversions):
+ makeonecgpart(newpart, repo, outgoing, version, source, bundlecaps,
+ filematcher, cgversions)
+
+def _changegroupinfo(repo, nodes, source):
+ if repo.ui.verbose or source == 'bundle':
+ repo.ui.status(_("%d changesets found\n") % len(nodes))
+
+def makeonecgpart(newpart, repo, outgoing, version, source,
+ bundlecaps, filematcher, cgversions):
+ # same as upstream code
+
+ old = changegroup._changegroupinfo
+ try:
+ changegroup._changegroupinfo = _changegroupinfo
+ cgstream = changegroup.makestream(repo, outgoing, version, source,
+ bundlecaps=bundlecaps,
+ filematcher=filematcher)
+ finally:
+ changegroup._changegroupinfo = old
+
+ part = newpart('changegroup', data=cgstream)
+ if cgversions:
+ part.addparam('version', version)
+
+ part.addparam('nbchanges', '%d' % len(outgoing.missing),
+ mandatory=False)
+
+ if 'treemanifest' in repo.requirements:
+ part.addparam('treemanifest', '1')