exchange: return bundle info from getbundlechunks() (API)
authorGregory Szorc <gregory.szorc@gmail.com>
Sat, 20 Jan 2018 13:41:57 -0800
changeset 35785 ba15580e53d5
parent 35784 08cc94dd3d3c
child 35786 8144f1b07e21
exchange: return bundle info from getbundlechunks() (API) We generally want a mechanism to pass information about the generated bundle back to callers (in addition to the byte stream). Ideally we would return a bundler from this function and have the caller code to an interface. But the bundling APIs are not great and getbundlechunks() is the best API we have for obtaining bundle contents in a unified manner. We change getbundlechunks() to return a dict that we can use to communicate metadata. We populate that dict with the bundle version number to demonstrate some value. .. api:: exchange.getbundlechunks() now returns a 2-tuple instead of just an iterator. Differential Revision: https://phab.mercurial-scm.org/D1925
mercurial/exchange.py
mercurial/localrepo.py
mercurial/wireproto.py
--- a/mercurial/exchange.py	Sat Jan 20 15:26:31 2018 -0800
+++ b/mercurial/exchange.py	Sat Jan 20 13:41:57 2018 -0800
@@ -1727,9 +1727,11 @@
     Could be a bundle HG10 or a bundle HG20 depending on bundlecaps
     passed.
 
-    Returns an iterator over raw chunks (of varying sizes).
+    Returns a 2-tuple of a dict with metadata about the generated bundle
+    and an iterator over raw chunks (of varying sizes).
     """
     kwargs = pycompat.byteskwargs(kwargs)
+    info = {}
     usebundle2 = bundle2requested(bundlecaps)
     # bundle10 case
     if not usebundle2:
@@ -1740,10 +1742,12 @@
             raise ValueError(_('unsupported getbundle arguments: %s')
                              % ', '.join(sorted(kwargs.keys())))
         outgoing = _computeoutgoing(repo, heads, common)
-        return changegroup.makestream(repo, outgoing, '01', source,
-                                      bundlecaps=bundlecaps)
+        info['bundleversion'] = 1
+        return info, changegroup.makestream(repo, outgoing, '01', source,
+                                            bundlecaps=bundlecaps)
 
     # bundle20 case
+    info['bundleversion'] = 2
     b2caps = {}
     for bcaps in bundlecaps:
         if bcaps.startswith('bundle2='):
@@ -1759,7 +1763,7 @@
         func(bundler, repo, source, bundlecaps=bundlecaps, b2caps=b2caps,
              **pycompat.strkwargs(kwargs))
 
-    return bundler.getchunks()
+    return info, bundler.getchunks()
 
 @getbundle2partsgenerator('stream')
 def _getbundlestream(bundler, repo, source, bundlecaps=None,
--- a/mercurial/localrepo.py	Sat Jan 20 15:26:31 2018 -0800
+++ b/mercurial/localrepo.py	Sat Jan 20 13:41:57 2018 -0800
@@ -197,7 +197,7 @@
                   **kwargs):
         chunks = exchange.getbundlechunks(self._repo, source, heads=heads,
                                           common=common, bundlecaps=bundlecaps,
-                                          **kwargs)
+                                          **kwargs)[1]
         cb = util.chunkbuffer(chunks)
 
         if exchange.bundle2requested(bundlecaps):
--- a/mercurial/wireproto.py	Sat Jan 20 15:26:31 2018 -0800
+++ b/mercurial/wireproto.py	Sat Jan 20 13:41:57 2018 -0800
@@ -877,8 +877,8 @@
                     _('server has pull-based clones disabled'),
                     hint=_('remove --pull if specified or upgrade Mercurial'))
 
-        chunks = exchange.getbundlechunks(repo, 'serve',
-                                          **pycompat.strkwargs(opts))
+        info, chunks = exchange.getbundlechunks(repo, 'serve',
+                                                **pycompat.strkwargs(opts))
     except error.Abort as exc:
         # cleanly forward Abort error to the client
         if not exchange.bundle2requested(opts.get('bundlecaps')):