pullbundle: initial commit
authorPierre-Yves David <pierre-yves.david@octobus.net>
Sun, 23 Sep 2018 23:53:23 +0200
changeset 4128 4e5ec9ae682e
parent 4127 dfa69b5ece87
child 4129 bc4e62a1cb82
pullbundle: initial commit Right now, we do not do any slicing, but we install the wrapping and the tests.
hgext3rd/pullbundle.py
tests/test-pullbundle.t
--- /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')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-pullbundle.t	Sun Sep 23 23:53:23 2018 +0200
@@ -0,0 +1,208 @@
+  $ . "$TESTDIR/testlib/pythonpath.sh"
+
+  $ cat << EOF >> $HGRCPATH
+  > [extensions]
+  > pullbundle=
+  > EOF
+
+basic setup
+
+  $ hg init server
+  $ hg -R server debugbuilddag '.+898:branchpoint+352:mergepoint+267<branchpoint+145/mergepoint+467'
+  $ hg init client
+
+simple initial pull
+-------------------
+
+  $ hg -R client pull server -r 1234 --debug --config devel.bundle2.debug=yes | grep -v 'add changeset'
+  pulling from server
+  query 1; heads
+  1235 changesets found
+  listing keys for "bookmarks"
+  bundle2-output-bundle: "HG20", 4 parts total
+  bundle2-output: start emission of HG20 stream
+  bundle2-output: bundle parameter: 
+  bundle2-output: start of parts
+  bundle2-output: bundle part: "changegroup"
+  bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
+  bundle2-output: part 0: "CHANGEGROUP"
+  bundle2-output: header chunk size: 44
+  bundle2-output: payload chunk size: 32768
+  bundle2-output: payload chunk size: 32768
+  bundle2-output: payload chunk size: 32768
+  bundle2-output: payload chunk size: 32768
+  bundle2-output: payload chunk size: 32768
+  bundle2-output: payload chunk size: 32768
+  bundle2-output: payload chunk size: 28424
+  bundle2-output: closing payload chunk
+  bundle2-output: bundle part: "listkeys"
+  bundle2-output-part: "listkeys" (params: 1 mandatory) empty payload
+  bundle2-output: part 1: "LISTKEYS"
+  bundle2-output: header chunk size: 35
+  bundle2-output: closing payload chunk
+  bundle2-output: bundle part: "phase-heads"
+  bundle2-output-part: "phase-heads" 24 bytes payload
+  bundle2-output: part 2: "PHASE-HEADS"
+  bundle2-output: header chunk size: 18
+  bundle2-output: payload chunk size: 24
+  bundle2-output: closing payload chunk
+  bundle2-output: bundle part: "cache:rev-branch-cache"
+  bundle2-output-part: "cache:rev-branch-cache" (advisory) streamed payload
+  bundle2-output: part 3: "cache:rev-branch-cache"
+  bundle2-output: header chunk size: 29
+  bundle2-output: payload chunk size: 24719
+  bundle2-output: closing payload chunk
+  bundle2-output: end of bundle
+  bundle2-input: start processing of HG20 stream
+  bundle2-input: reading bundle2 stream parameters
+  bundle2-input-bundle: with-transaction
+  bundle2-input: start extraction of bundle2 parts
+  bundle2-input: part header size: 44
+  bundle2-input: part type: "CHANGEGROUP"
+  bundle2-input: part id: "0"
+  bundle2-input: part parameters: 2
+  bundle2-input: found a handler for part changegroup
+  bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
+  adding changesets
+  bundle2-input: payload chunk size: 32768
+  bundle2-input: payload chunk size: 32768
+  bundle2-input: payload chunk size: 32768
+  bundle2-input: payload chunk size: 32768
+  bundle2-input: payload chunk size: 32768
+  bundle2-input: payload chunk size: 32768
+  bundle2-input: payload chunk size: 28424
+  bundle2-input: payload chunk size: 0
+  adding manifests
+  adding file changes
+  added 1235 changesets with 0 changes to 0 files
+  bundle2-input-part: total payload size 225032
+  bundle2-input: part header size: 35
+  bundle2-input: part type: "LISTKEYS"
+  bundle2-input: part id: "1"
+  bundle2-input: part parameters: 1
+  bundle2-input: found a handler for part listkeys
+  bundle2-input-part: "listkeys" (params: 1 mandatory) supported
+  bundle2-input: payload chunk size: 0
+  bundle2-input: part header size: 18
+  bundle2-input: part type: "PHASE-HEADS"
+  bundle2-input: part id: "2"
+  bundle2-input: part parameters: 0
+  bundle2-input: found a handler for part phase-heads
+  bundle2-input-part: "phase-heads" supported
+  bundle2-input: payload chunk size: 24
+  bundle2-input: payload chunk size: 0
+  bundle2-input-part: total payload size 24
+  bundle2-input: part header size: 29
+  bundle2-input: part type: "cache:rev-branch-cache"
+  bundle2-input: part id: "3"
+  bundle2-input: part parameters: 0
+  bundle2-input: found a handler for part cache:rev-branch-cache
+  bundle2-input-part: "cache:rev-branch-cache" (advisory) supported
+  bundle2-input: payload chunk size: 24719
+  bundle2-input: payload chunk size: 0
+  bundle2-input-part: total payload size 24719
+  bundle2-input: part header size: 0
+  bundle2-input: end of bundle2 stream
+  bundle2-input-bundle: 3 parts total
+  checking for updated bookmarks
+  updating the branch cache
+  new changesets 1ea73414a91b:f864bc82f6a2
+  (run 'hg update' to get a working copy)
+
+pull the other missing entries (multiple heads pulled)
+------------------------------------------------------
+
+  $ hg -R client pull server --debug --config devel.bundle2.debug=yes | grep -v 'add changeset'
+  pulling from server
+  query 1; heads
+  searching for changes
+  all local heads known remotely
+  896 changesets found
+  listing keys for "bookmarks"
+  bundle2-output-bundle: "HG20", 4 parts total
+  bundle2-output: start emission of HG20 stream
+  bundle2-output: bundle parameter: 
+  bundle2-output: start of parts
+  bundle2-output: bundle part: "changegroup"
+  bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
+  bundle2-output: part 0: "CHANGEGROUP"
+  bundle2-output: header chunk size: 43
+  bundle2-output: payload chunk size: 32768
+  bundle2-output: payload chunk size: 32768
+  bundle2-output: payload chunk size: 32768
+  bundle2-output: payload chunk size: 32768
+  bundle2-output: payload chunk size: 32768
+  bundle2-output: payload chunk size: 1036
+  bundle2-output: closing payload chunk
+  bundle2-output: bundle part: "listkeys"
+  bundle2-output-part: "listkeys" (params: 1 mandatory) empty payload
+  bundle2-output: part 1: "LISTKEYS"
+  bundle2-output: header chunk size: 35
+  bundle2-output: closing payload chunk
+  bundle2-output: bundle part: "phase-heads"
+  bundle2-output-part: "phase-heads" 48 bytes payload
+  bundle2-output: part 2: "PHASE-HEADS"
+  bundle2-output: header chunk size: 18
+  bundle2-output: payload chunk size: 48
+  bundle2-output: closing payload chunk
+  bundle2-output: bundle part: "cache:rev-branch-cache"
+  bundle2-output-part: "cache:rev-branch-cache" (advisory) streamed payload
+  bundle2-output: part 3: "cache:rev-branch-cache"
+  bundle2-output: header chunk size: 29
+  bundle2-output: payload chunk size: 17939
+  bundle2-output: closing payload chunk
+  bundle2-output: end of bundle
+  bundle2-input: start processing of HG20 stream
+  bundle2-input: reading bundle2 stream parameters
+  bundle2-input-bundle: with-transaction
+  bundle2-input: start extraction of bundle2 parts
+  bundle2-input: part header size: 43
+  bundle2-input: part type: "CHANGEGROUP"
+  bundle2-input: part id: "0"
+  bundle2-input: part parameters: 2
+  bundle2-input: found a handler for part changegroup
+  bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
+  adding changesets
+  bundle2-input: payload chunk size: 32768
+  bundle2-input: payload chunk size: 32768
+  bundle2-input: payload chunk size: 32768
+  bundle2-input: payload chunk size: 32768
+  bundle2-input: payload chunk size: 32768
+  bundle2-input: payload chunk size: 1036
+  bundle2-input: payload chunk size: 0
+  adding manifests
+  adding file changes
+  added 896 changesets with 0 changes to 0 files (+1 heads)
+  bundle2-input-part: total payload size 164876
+  bundle2-input: part header size: 35
+  bundle2-input: part type: "LISTKEYS"
+  bundle2-input: part id: "1"
+  bundle2-input: part parameters: 1
+  bundle2-input: found a handler for part listkeys
+  bundle2-input-part: "listkeys" (params: 1 mandatory) supported
+  bundle2-input: payload chunk size: 0
+  bundle2-input: part header size: 18
+  bundle2-input: part type: "PHASE-HEADS"
+  bundle2-input: part id: "2"
+  bundle2-input: part parameters: 0
+  bundle2-input: found a handler for part phase-heads
+  bundle2-input-part: "phase-heads" supported
+  bundle2-input: payload chunk size: 48
+  bundle2-input: payload chunk size: 0
+  bundle2-input-part: total payload size 48
+  bundle2-input: part header size: 29
+  bundle2-input: part type: "cache:rev-branch-cache"
+  bundle2-input: part id: "3"
+  bundle2-input: part parameters: 0
+  bundle2-input: found a handler for part cache:rev-branch-cache
+  bundle2-input-part: "cache:rev-branch-cache" (advisory) supported
+  bundle2-input: payload chunk size: 17939
+  bundle2-input: payload chunk size: 0
+  bundle2-input-part: total payload size 17939
+  bundle2-input: part header size: 0
+  bundle2-input: end of bundle2 stream
+  bundle2-input-bundle: 3 parts total
+  checking for updated bookmarks
+  updating the branch cache
+  new changesets 17185c1c22f1:0f376356904f
+  (run 'hg heads' to see heads, 'hg merge' to merge)