Patchwork [v3] changegroup.writebundle: HG2Y support

login
register
mail settings
Submitter Eric Sumner
Date Jan. 17, 2015, 12:31 a.m.
Message ID <9fe3a0f81d0f98bf69c0.1421454661@dev911.prn1.facebook.com>
Download mbox | patch
Permalink /patch/7505/
State Accepted
Commit becfecaf9087f338d1248aea52416b30d4e145d3
Headers show

Comments

Eric Sumner - Jan. 17, 2015, 12:31 a.m.
# HG changeset patch
# User Eric Sumner <ericsumner@fb.com>
# Date 1421365156 28800
#      Thu Jan 15 15:39:16 2015 -0800
# Node ID 9fe3a0f81d0f98bf69c0b01677f34d44c56f9fc0
# Parent  6c6e87a308429cd9b654cafd4ed3c834e13999b4
changegroup.writebundle: HG2Y support

This diff adds support to writebundle to generate a bundle2 wrapper; upcoming
diffs will add an option to write a v2 changegroup part instead of v1 in these
bundles.
Matt Mackall - Jan. 17, 2015, 12:45 a.m.
On Fri, 2015-01-16 at 16:31 -0800, Eric Sumner wrote:
> # HG changeset patch
> # User Eric Sumner <ericsumner@fb.com>
> # Date 1421365156 28800
> #      Thu Jan 15 15:39:16 2015 -0800
> # Node ID 9fe3a0f81d0f98bf69c0b01677f34d44c56f9fc0
> # Parent  6c6e87a308429cd9b654cafd4ed3c834e13999b4
> changegroup.writebundle: HG2Y support

Queued for default, thanks.

Patch

diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py
--- a/mercurial/changegroup.py
+++ b/mercurial/changegroup.py
@@ -71,6 +71,7 @@ 
     "": ("", nocompress), # only when using unbundle on ssh and old http servers
                           # since the unification ssh accepts a header but there
                           # is no capability signaling it.
+    "HG2Y": (), # special-cased below
     "HG10UN": ("HG10UN", nocompress),
     "HG10BZ": ("HG10", lambda: bz2.BZ2Compressor()),
     "HG10GZ": ("HG10GZ", lambda: zlib.compressobj()),
@@ -101,9 +102,20 @@ 
             fh = os.fdopen(fd, "wb")
         cleanup = filename
 
-        header, compressor = bundletypes[bundletype]
-        fh.write(header)
-        z = compressor()
+        if bundletype == "HG2Y":
+            import bundle2
+            bundle = bundle2.bundle20(ui)
+            part = bundle.newpart('b2x:changegroup', data=cg.getchunks())
+            part.addparam('version', cg.version)
+            z = nocompress()
+            chunkiter = bundle.getchunks()
+        else:
+            if cg.version != '01':
+                raise util.Abort(_('Bundle1 only supports v1 changegroups\n'))
+            header, compressor = bundletypes[bundletype]
+            fh.write(header)
+            z = compressor()
+            chunkiter = cg.getchunks()
 
         # parse the changegroup data, otherwise we will block
         # in case of sshrepo because we don't know the end of the stream
@@ -111,7 +123,7 @@ 
         # an empty chunkgroup is the end of the changegroup
         # a changegroup has at least 2 chunkgroups (changelog and manifest).
         # after that, an empty chunkgroup is the end of the changegroup
-        for chunk in cg.getchunks():
+        for chunk in chunkiter:
             fh.write(z.compress(chunk))
         fh.write(z.flush())
         cleanup = None
@@ -146,6 +158,7 @@ 
 class cg1unpacker(object):
     deltaheader = _CHANGEGROUPV1_DELTA_HEADER
     deltaheadersize = struct.calcsize(deltaheader)
+    version = '01'
     def __init__(self, fh, alg):
         self._stream = decompressor(fh, alg)
         self._type = alg
@@ -238,6 +251,7 @@ 
 class cg2unpacker(cg1unpacker):
     deltaheader = _CHANGEGROUPV2_DELTA_HEADER
     deltaheadersize = struct.calcsize(deltaheader)
+    version = '02'
 
     def _deltaheader(self, headertuple, prevnode):
         node, p1, p2, deltabase, cs = headertuple
@@ -257,6 +271,7 @@ 
 
 class cg1packer(object):
     deltaheader = _CHANGEGROUPV1_DELTA_HEADER
+    version = '01'
     def __init__(self, repo, bundlecaps=None):
         """Given a source repo, construct a bundler.
 
@@ -484,7 +499,7 @@ 
         return struct.pack(self.deltaheader, node, p1n, p2n, linknode)
 
 class cg2packer(cg1packer):
-
+    version = '02'
     deltaheader = _CHANGEGROUPV2_DELTA_HEADER
 
     def group(self, nodelist, revlog, lookup, units=None, reorder=None):
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -1181,7 +1181,10 @@ 
         revs = scmutil.revrange(repo, opts['rev'])
 
     bundletype = opts.get('type', 'bzip2').lower()
-    btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
+    btypes = {'none': 'HG10UN',
+              'bzip2': 'HG10BZ',
+              'gzip': 'HG10GZ',
+              'bundle2': 'HG2Y'}
     bundletype = btypes.get(bundletype)
     if bundletype not in changegroup.bundletypes:
         raise util.Abort(_('unknown bundle type specified with --type'))
@@ -2161,7 +2164,10 @@ 
     bundle = repo.getbundle('debug', **args)
 
     bundletype = opts.get('type', 'bzip2').lower()
-    btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
+    btypes = {'none': 'HG10UN',
+              'bzip2': 'HG10BZ',
+              'gzip': 'HG10GZ',
+              'bundle2': 'HG2Y'}
     bundletype = btypes.get(bundletype)
     if bundletype not in changegroup.bundletypes:
         raise util.Abort(_('unknown bundle type specified with --type'))
diff --git a/tests/test-getbundle.t b/tests/test-getbundle.t
--- a/tests/test-getbundle.t
+++ b/tests/test-getbundle.t
@@ -165,7 +165,30 @@ 
   8365676dbab05860ce0d9110f2af51368b961bbd
   0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
 
+= Test bundle2 =
 
+  $ hg debuggetbundle repo bundle -t bundle2
+  $ hg debugbundle bundle
+  Stream params: {}
+  b2x:changegroup -- "{'version': '01'}"
+      7704483d56b2a7b5db54dcee7c62378ac629b348
+      29a4d1f17bd3f0779ca0525bebb1cfb51067c738
+      713346a995c363120712aed1aee7e04afd867638
+      d5f6e1ea452285324836a49d7d3c2a63cfed1d31
+      ff42371d57168345fdf1a3aac66a51f6a45d41d2
+      bac16991d12ff45f9dc43c52da1946dfadb83e80
+      6621d79f61b23ec74cf4b69464343d9e0980ec8b
+      8931463777131cd73923e560b760061f2aa8a4bc
+      f34414c64173e0ecb61b25dc55e116dbbcc89bee
+      928b5f94cdb278bb536eba552de348a4e92ef24d
+      700b7e19db54103633c4bf4a6a6b6d55f4d50c03
+      63476832d8ec6558cf9bbe3cbe0c757e5cf18043
+      13c0170174366b441dc68e8e33757232fa744458
+      5686dbbd9fc46cb806599c878d02fe1cb56b83d3
+      8365676dbab05860ce0d9110f2af51368b961bbd
+      0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
+      4801a72e5d88cb515b0c7e40fae34180f3f837f2
+      10c14a2cc935e1d8c31f9e98587dcf27fb08a6da
 = Test via HTTP =
 
 Get everything: