@@ -1527,43 +1527,37 @@ def getbundle2partsgenerator(stepname, i
return func
return dec
def bundle2requested(bundlecaps):
if bundlecaps is not None:
return any(cap.startswith('HG2') for cap in bundlecaps)
return False
-def getbundle(repo, source, heads=None, common=None, bundlecaps=None,
- **kwargs):
- """return a full bundle (with potentially multiple kind of parts)
+def getbundlechunks(repo, source, heads=None, common=None, bundlecaps=None,
+ **kwargs):
+ """Return chunks constituting a bundle's raw data.
Could be a bundle HG10 or a bundle HG20 depending on bundlecaps
- passed. For now, the bundle can contain only changegroup, but this will
- changes when more part type will be available for bundle2.
+ passed.
- This is different from changegroup.getchangegroup that only returns an HG10
- changegroup bundle. They may eventually get reunited in the future when we
- have a clearer idea of the API we what to query different data.
-
- The implementation is at a very early stage and will get massive rework
- when the API of bundle is refined.
+ Returns an iterator over raw chunks (of varying sizes).
"""
usebundle2 = bundle2requested(bundlecaps)
# bundle10 case
if not usebundle2:
if bundlecaps and not kwargs.get('cg', True):
raise ValueError(_('request for bundle10 must include changegroup'))
if kwargs:
raise ValueError(_('unsupported getbundle arguments: %s')
% ', '.join(sorted(kwargs.keys())))
outgoing = _computeoutgoing(repo, heads, common)
- return changegroup.getchangegroup(repo, source, outgoing,
- bundlecaps=bundlecaps)
+ bundler = changegroup.getbundler('01', repo, bundlecaps)
+ return changegroup.getsubsetraw(repo, outgoing, bundler, source)
# bundle20 case
b2caps = {}
for bcaps in bundlecaps:
if bcaps.startswith('bundle2='):
blob = urlreq.unquote(bcaps[len('bundle2='):])
b2caps.update(bundle2.decodecaps(blob))
bundler = bundle2.bundle20(repo.ui, b2caps)
@@ -1571,17 +1565,17 @@ def getbundle(repo, source, heads=None,
kwargs['heads'] = heads
kwargs['common'] = common
for name in getbundle2partsorder:
func = getbundle2partsmapping[name]
func(bundler, repo, source, bundlecaps=bundlecaps, b2caps=b2caps,
**kwargs)
- return util.chunkbuffer(bundler.getchunks())
+ return bundler.getchunks()
@getbundle2partsgenerator('changegroup')
def _getbundlechangegrouppart(bundler, repo, source, bundlecaps=None,
b2caps=None, heads=None, common=None, **kwargs):
"""add a changegroup part to the requested bundle"""
cg = None
if kwargs.get('cg', True):
# build changegroup bundle here.
@@ -144,24 +144,28 @@ class localpeer(peer.peerrepository):
def heads(self):
return self._repo.heads()
def known(self, nodes):
return self._repo.known(nodes)
def getbundle(self, source, heads=None, common=None, bundlecaps=None,
**kwargs):
- cg = exchange.getbundle(self._repo, source, heads=heads,
- common=common, bundlecaps=bundlecaps, **kwargs)
+ chunks = exchange.getbundlechunks(self._repo, source, heads=heads,
+ common=common, bundlecaps=bundlecaps,
+ **kwargs)
+ cb = util.chunkbuffer(chunks)
+
if bundlecaps is not None and 'HG20' in bundlecaps:
# When requesting a bundle2, getbundle returns a stream to make the
# wire level function happier. We need to build a proper object
# from it in local peer.
- cg = bundle2.getunbundler(self.ui, cg)
- return cg
+ return bundle2.getunbundler(self.ui, cb)
+ else:
+ return changegroup.getunbundler('01', cb, None)
# TODO We might want to move the next two calls into legacypeer and add
# unbundle instead.
def unbundle(self, cg, heads, url):
"""apply a bundle on a repo
This function handles the repo locking itself."""
@@ -767,18 +767,20 @@ def getbundle(repo, proto, others):
elif keytype != 'plain':
raise KeyError('unknown getbundle option type %s'
% keytype)
if not bundle1allowed(repo, 'pull'):
if not exchange.bundle2requested(opts.get('bundlecaps')):
return ooberror(bundle2required)
- cg = exchange.getbundle(repo, 'serve', **opts)
- return streamres(proto.groupchunks(cg))
+ chunks = exchange.getbundlechunks(repo, 'serve', **opts)
+ # TODO avoid util.chunkbuffer() here since it is adding overhead to
+ # what is fundamentally a generator proxying operation.
+ return streamres(proto.groupchunks(util.chunkbuffer(chunks)))
@wireprotocommand('heads')
def heads(repo, proto):
h = repo.heads()
return encodelist(h) + "\n"
@wireprotocommand('hello')
def hello(repo, proto):
@@ -165,17 +165,17 @@ Get branch and merge:
8365676dbab05860ce0d9110f2af51368b961bbd
0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
= Test bundle2 =
$ hg debuggetbundle repo bundle -t bundle2
$ hg debugbundle bundle
Stream params: {}
- changegroup -- "sortdict([('version', '01'), ('nbchanges', '18')])"
+ changegroup -- "sortdict([('version', '01')])"
7704483d56b2a7b5db54dcee7c62378ac629b348
29a4d1f17bd3f0779ca0525bebb1cfb51067c738
713346a995c363120712aed1aee7e04afd867638
d5f6e1ea452285324836a49d7d3c2a63cfed1d31
ff42371d57168345fdf1a3aac66a51f6a45d41d2
bac16991d12ff45f9dc43c52da1946dfadb83e80
6621d79f61b23ec74cf4b69464343d9e0980ec8b
8931463777131cd73923e560b760061f2aa8a4bc