Patchwork [3,of,4] bundle2: add an exchange.getbundle function

mail settings
Submitter Pierre-Yves David
Date April 4, 2014, 10:29 p.m.
Message ID <>
Download mbox | patch
Permalink /patch/4232/
State Accepted
Commit dba91f8060eb57cad9beb71a6fcef341f5f9f7fd
Headers show


Pierre-Yves David - April 4, 2014, 10:29 p.m.
# HG changeset patch
# User Pierre-Yves David <>
# Date 1396601514 25200
#      Fri Apr 04 01:51:54 2014 -0700
# Node ID 7d8624d40967bb222986f5dbad9ebc2e11464fa4
# Parent  f9276e9909ad16a264126c7256efcae8f1212955
bundle2: add an exchange.getbundle function

This function can return a `HG10` or `HG20` bundle. It use the `bundlecaps`
parameters to decides to which one to return.

This is a distinct function from `changegroup.getbundle` for two reasons. First
the APIs of `bundle10` and `bundle20` are not compatible yet. The two functions
may be reunited in the future. Second `exchange.getbundle` will grow parameters
for all kinds of data (phases, obsmarkers, ...) so it's better to keep the
changegroup generation in its own function for now.

This function will be used it in the next changesets.


diff --git a/mercurial/ b/mercurial/
--- a/mercurial/
+++ b/mercurial/
@@ -550,5 +550,36 @@  def _pullobsolete(pullop):
                     data = base85.b85decode(remoteobs[key])
                     pullop.repo.obsstore.mergemarkers(tr, data)
     return tr
+def getbundle(repo, source, heads=None, common=None, bundlecaps=None):
+    """return a full bundle (with potentially multiple kind of parts)
+    Could be a bundle HG10 or a bundle HG20 will depends of the bundlescaps
+    passed. For now, the bundle can contains only changegroup, but this will
+    changes when more part type will be available for bundle2.
+    This is different from changegroup.getbundle that only returns 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 very early stage and will get massive rework when
+    the API of bundle will be refined.
+    """
+    # build bundle here.
+    cg = changegroup.getbundle(repo, source, heads=heads,
+                               common=common, bundlecaps=None)
+    if bundlecaps is None or 'HG20' not in bundlecaps:
+        return cg
+    # very crude first implementation,
+    # the bundle API will change and the generation will be done lazily.
+    bundler = bundle2.bundle20(repo.ui)
+    tempname = changegroup.writebundle(cg, None, 'HG10UN')
+    data = open(tempname).read()
+    part = bundle2.part('changegroup', data=data)
+    bundler.addpart(part)
+    temp = cStringIO.StringIO()
+    for c in bundler.getchunks():
+        temp.write(c)
+    return bundle2.unbundle20(repo.ui, temp)
diff --git a/mercurial/ b/mercurial/
--- a/mercurial/
+++ b/mercurial/
@@ -103,12 +103,12 @@  class localpeer(peer.peerrepository):
     def known(self, nodes):
         return self._repo.known(nodes)
     def getbundle(self, source, heads=None, common=None, bundlecaps=None,
-        return changegroup.getbundle(self._repo, source, heads=heads,
-                                     common=common, bundlecaps=bundlecaps)
+        return exchange.getbundle(self._repo, source, heads=heads,
+                                  common=common, bundlecaps=bundlecaps)
     # TODO We might want to move the next two calls into legacypeer and add
     # unbundle instead.
     def lock(self):