changeset 32287:df3cf9422e1b

changegroup: add bundlecaps back Commit 282b288aa20c333c removed the unused bundlecaps argument from the changegroup code. While it is unused in core Mercurial, it was an important feature for the remotefilelog extension because it allowed the exchange layer to communicate to the changegroup packer that this was a shallow repo and that filelogs should not be included. Without bundlecaps, there is currently no other way to pass that information along without a more extensive refactor of exchange, bundle, and changegroup code. This patch backs out the original removal, and merges it with some recent changes to changegroup apis.
author Durham Goode <durham@fb.com>
date Mon, 15 May 2017 09:35:27 -0700
parents 539cbe0f8fa3
children a2ab9ebcd85b
files mercurial/changegroup.py mercurial/exchange.py tests/test-bundle2-format.t tests/test-bundle2-multiple-changegroups.t
diffstat 4 files changed, 32 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/changegroup.py	Wed May 10 16:17:58 2017 -0700
+++ b/mercurial/changegroup.py	Mon May 15 09:35:27 2017 -0700
@@ -494,9 +494,18 @@
 class cg1packer(object):
     deltaheader = _CHANGEGROUPV1_DELTA_HEADER
     version = '01'
-    def __init__(self, repo):
+    def __init__(self, repo, bundlecaps=None):
         """Given a source repo, construct a bundler.
+
+        bundlecaps is optional and can be used to specify the set of
+        capabilities which can be used to build the bundle. While bundlecaps is
+        unused in core Mercurial, extensions rely on this feature to communicate
+        capabilities to customize the changegroup packer.
         """
+        # Set of capabilities we can use to build the bundle.
+        if bundlecaps is None:
+            bundlecaps = set()
+        self._bundlecaps = bundlecaps
         # experimental config: bundle.reorder
         reorder = repo.ui.config('bundle', 'reorder', 'auto')
         if reorder == 'auto':
@@ -800,8 +809,8 @@
     version = '02'
     deltaheader = _CHANGEGROUPV2_DELTA_HEADER
 
-    def __init__(self, repo):
-        super(cg2packer, self).__init__(repo)
+    def __init__(self, repo, bundlecaps=None):
+        super(cg2packer, self).__init__(repo, bundlecaps)
         if self._reorder is None:
             # Since generaldelta is directly supported by cg2, reordering
             # generally doesn't help, so we disable it by default (treating
@@ -895,9 +904,9 @@
     assert versions
     return min(versions)
 
-def getbundler(version, repo):
+def getbundler(version, repo, bundlecaps=None):
     assert version in supportedoutgoingversions(repo)
-    return _packermap[version][0](repo)
+    return _packermap[version][0](repo, bundlecaps)
 
 def getunbundler(version, fh, alg, extras=None):
     return _packermap[version][1](fh, alg, extras=extras)
@@ -948,24 +957,26 @@
     bundler = getbundler(version, repo)
     return getsubset(repo, outgoing, bundler, source)
 
-def getlocalchangegroupraw(repo, source, outgoing, version='01'):
+def getlocalchangegroupraw(repo, source, outgoing, bundlecaps=None,
+                           version='01'):
     """Like getbundle, but taking a discovery.outgoing as an argument.
 
     This is only implemented for local repos and reuses potentially
     precomputed sets in outgoing. Returns a raw changegroup generator."""
     if not outgoing.missing:
         return None
-    bundler = getbundler(version, repo)
+    bundler = getbundler(version, repo, bundlecaps)
     return getsubsetraw(repo, outgoing, bundler, source)
 
-def getchangegroup(repo, source, outgoing, version='01'):
+def getchangegroup(repo, source, outgoing, bundlecaps=None,
+                   version='01'):
     """Like getbundle, but taking a discovery.outgoing as an argument.
 
     This is only implemented for local repos and reuses potentially
     precomputed sets in outgoing."""
     if not outgoing.missing:
         return None
-    bundler = getbundler(version, repo)
+    bundler = getbundler(version, repo, bundlecaps)
     return getsubset(repo, outgoing, bundler, source)
 
 def getlocalchangegroup(repo, *args, **kwargs):
--- a/mercurial/exchange.py	Wed May 10 16:17:58 2017 -0700
+++ b/mercurial/exchange.py	Mon May 15 09:35:27 2017 -0700
@@ -936,19 +936,22 @@
     pushop.repo.prepushoutgoinghooks(pushop)
     outgoing = pushop.outgoing
     unbundle = pushop.remote.capable('unbundle')
+    # TODO: get bundlecaps from remote
+    bundlecaps = None
     # create a changegroup from local
     if pushop.revs is None and not (outgoing.excluded
                             or pushop.repo.changelog.filteredrevs):
         # push everything,
         # use the fast path, no race possible on push
-        bundler = changegroup.cg1packer(pushop.repo)
+        bundler = changegroup.cg1packer(pushop.repo, bundlecaps)
         cg = changegroup.getsubset(pushop.repo,
                                    outgoing,
                                    bundler,
                                    'push',
                                    fastpath=True)
     else:
-        cg = changegroup.getchangegroup(pushop.repo, 'push', outgoing)
+        cg = changegroup.getchangegroup(pushop.repo, 'push', outgoing,
+                                        bundlecaps=bundlecaps)
 
     # apply changegroup to remote
     if unbundle:
@@ -1575,7 +1578,7 @@
             raise ValueError(_('unsupported getbundle arguments: %s')
                              % ', '.join(sorted(kwargs.keys())))
         outgoing = _computeoutgoing(repo, heads, common)
-        bundler = changegroup.getbundler('01', repo)
+        bundler = changegroup.getbundler('01', repo, bundlecaps)
         return changegroup.getsubsetraw(repo, outgoing, bundler, source)
 
     # bundle20 case
@@ -1613,6 +1616,7 @@
             version = max(cgversions)
         outgoing = _computeoutgoing(repo, heads, common)
         cg = changegroup.getlocalchangegroupraw(repo, source, outgoing,
+                                                bundlecaps=bundlecaps,
                                                 version=version)
 
     if cg:
--- a/tests/test-bundle2-format.t	Wed May 10 16:17:58 2017 -0700
+++ b/tests/test-bundle2-format.t	Mon May 15 09:35:27 2017 -0700
@@ -113,7 +113,7 @@
   >             headmissing = [c.node() for c in repo.set('heads(%ld)', revs)]
   >             headcommon  = [c.node() for c in repo.set('parents(%ld) - %ld', revs, revs)]
   >             outgoing = discovery.outgoing(repo, headcommon, headmissing)
-  >             cg = changegroup.getchangegroup(repo, 'test:bundle2', outgoing)
+  >             cg = changegroup.getchangegroup(repo, 'test:bundle2', outgoing, None)
   >             bundler.newpart('changegroup', data=cg.getchunks(),
   >                             mandatory=False)
   > 
--- a/tests/test-bundle2-multiple-changegroups.t	Wed May 10 16:17:58 2017 -0700
+++ b/tests/test-bundle2-multiple-changegroups.t	Mon May 15 09:35:27 2017 -0700
@@ -13,11 +13,13 @@
   >     # in 'heads' as intermediate heads for the first changegroup.
   >     intermediates = [repo[r].p1().node() for r in heads]
   >     outgoing = discovery.outgoing(repo, common, intermediates)
-  >     cg = changegroup.getchangegroup(repo, source, outgoing)
+  >     cg = changegroup.getchangegroup(repo, source, outgoing,
+  >                                     bundlecaps=bundlecaps)
   >     bundler.newpart('output', data='changegroup1')
   >     bundler.newpart('changegroup', data=cg.getchunks())
   >     outgoing = discovery.outgoing(repo, common + intermediates, heads)
-  >     cg = changegroup.getchangegroup(repo, source, outgoing)
+  >     cg = changegroup.getchangegroup(repo, source, outgoing,
+  >                                     bundlecaps=bundlecaps)
   >     bundler.newpart('output', data='changegroup2')
   >     bundler.newpart('changegroup', data=cg.getchunks())
   >