Patchwork D1925: exchange: return bundle info from getbundlechunks() (API)

login
register
mail settings
Submitter phabricator
Date Jan. 21, 2018, 12:45 a.m.
Message ID <differential-rev-PHID-DREV-b5be7zpuksaizlsmpixo-req@phab.mercurial-scm.org>
Download mbox | patch
Permalink /patch/27011/
State Superseded
Headers show

Comments

phabricator - Jan. 21, 2018, 12:45 a.m.
indygreg created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  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.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1925

AFFECTED FILES
  mercurial/exchange.py
  mercurial/localrepo.py
  mercurial/wireproto.py

CHANGE DETAILS




To: indygreg, #hg-reviewers
Cc: mercurial-devel
phabricator - Jan. 22, 2018, 4:01 p.m.
lothiraldan added a comment.


  Just an idea, instead of changing the return API of `getbundlechunks`, would it be possible of returning a (newly introduced) `bundlechunks` object which is also an iterator and where we could store such info?

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1925

To: indygreg, #hg-reviewers
Cc: lothiraldan, mercurial-devel
phabricator - Jan. 22, 2018, 8:03 p.m.
durin42 added a comment.


  In https://phab.mercurial-scm.org/D1925#32538, @lothiraldan wrote:
  
  > Just an idea, instead of changing the return API of `getbundlechunks`, would it be possible of returning a (newly introduced) `bundlechunks` object which is also an iterator and where we could store such info?
  
  
  Not a bad idea, but that's an idea for when we're not scrambling to get an rc out the door.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1925

To: indygreg, #hg-reviewers
Cc: durin42, lothiraldan, mercurial-devel

Patch

diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py
--- a/mercurial/wireproto.py
+++ b/mercurial/wireproto.py
@@ -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')):
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -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):
diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -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,