bundle: move writebundle() from changegroup.py to bundle2.py (API)
authorMartin von Zweigbergk <martinvonz@google.com>
Mon, 28 Mar 2016 14:41:29 -0700
changeset 28666 ae53ecc47414
parent 28655 0e330d7d9f53
child 28667 e7bf227e33a5
bundle: move writebundle() from changegroup.py to bundle2.py (API) writebundle() writes a bundle2 bundle or a plain changegroup1. Imagine away the "2" in "bundle2.py" for a moment and this change should makes sense. The bundle wraps the changegroup, so it makes sense that it knows about it. Another sign that this is correct is that the delayed import of bundle2 in changegroup goes away. I'll leave it for another time to remove the "2" in "bundle2.py" (alternatively, extract a new bundle.py from it).
hgext/shelve.py
mercurial/bundle2.py
mercurial/bundlerepo.py
mercurial/changegroup.py
mercurial/commands.py
mercurial/httppeer.py
mercurial/repair.py
mercurial/wireproto.py
--- a/hgext/shelve.py	Mon Mar 28 17:16:00 2016 -0500
+++ b/hgext/shelve.py	Mon Mar 28 14:41:29 2016 -0700
@@ -141,7 +141,7 @@
 
         cg = changegroup.changegroupsubset(self.repo, bases, [node], 'shelve',
                                            version=cgversion)
-        changegroup.writebundle(self.ui, cg, self.fname, btype, self.vfs,
+        bundle2.writebundle(self.ui, cg, self.fname, btype, self.vfs,
                                 compression=compression)
 
 class shelvedstate(object):
--- a/mercurial/bundle2.py	Mon Mar 28 17:16:00 2016 -0500
+++ b/mercurial/bundle2.py	Mon Mar 28 14:41:29 2016 -0700
@@ -474,6 +474,19 @@
         chunks.append(ca)
     return '\n'.join(chunks)
 
+bundletypes = {
+    "": ("", None),       # only when using unbundle on ssh and old http servers
+                          # since the unification ssh accepts a header but there
+                          # is no capability signaling it.
+    "HG20": (), # special-cased below
+    "HG10UN": ("HG10UN", None),
+    "HG10BZ": ("HG10", 'BZ'),
+    "HG10GZ": ("HG10GZ", 'GZ'),
+}
+
+# hgweb uses this list to communicate its preferred type
+bundlepriority = ['HG10GZ', 'HG10BZ', 'HG10UN']
+
 class bundle20(object):
     """represent an outgoing bundle2 container
 
@@ -1265,6 +1278,48 @@
     obscaps = caps.get('obsmarkers', ())
     return [int(c[1:]) for c in obscaps if c.startswith('V')]
 
+def writebundle(ui, cg, filename, bundletype, vfs=None, compression=None):
+    """Write a bundle file and return its filename.
+
+    Existing files will not be overwritten.
+    If no filename is specified, a temporary file is created.
+    bz2 compression can be turned off.
+    The bundle file will be deleted in case of errors.
+    """
+
+    if bundletype == "HG20":
+        bundle = bundle20(ui)
+        bundle.setcompression(compression)
+        part = bundle.newpart('changegroup', data=cg.getchunks())
+        part.addparam('version', cg.version)
+        chunkiter = bundle.getchunks()
+    else:
+        # compression argument is only for the bundle2 case
+        assert compression is None
+        if cg.version != '01':
+            raise error.Abort(_('old bundle types only supports v1 '
+                                'changegroups'))
+        header, comp = bundletypes[bundletype]
+        if comp not in util.compressors:
+            raise error.Abort(_('unknown stream compression type: %s')
+                              % comp)
+        z = util.compressors[comp]()
+        subchunkiter = cg.getchunks()
+        def chunkiter():
+            yield header
+            for chunk in subchunkiter:
+                yield z.compress(chunk)
+            yield z.flush()
+        chunkiter = chunkiter()
+
+    # parse the changegroup data, otherwise we will block
+    # in case of sshrepo because we don't know the end of the stream
+
+    # 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
+    return changegroup.writechunks(ui, chunkiter, filename, vfs=vfs)
+
 @parthandler('changegroup', ('version', 'nbchanges', 'treemanifest'))
 def handlechangegroup(op, inpart):
     """apply a changegroup part on the repo
--- a/mercurial/bundlerepo.py	Mon Mar 28 17:16:00 2016 -0500
+++ b/mercurial/bundlerepo.py	Mon Mar 28 14:41:29 2016 -0700
@@ -494,7 +494,7 @@
                 bundletype = "HG10BZ"
             else:
                 bundletype = "HG10UN"
-            fname = bundle = changegroup.writebundle(ui, cg, bundlename,
+            fname = bundle = bundle2.writebundle(ui, cg, bundlename,
                                                      bundletype)
         # keep written bundle?
         if bundlename:
--- a/mercurial/changegroup.py	Mon Mar 28 17:16:00 2016 -0500
+++ b/mercurial/changegroup.py	Mon Mar 28 14:41:29 2016 -0700
@@ -80,19 +80,6 @@
         result = -1 + changedheads
     return result
 
-bundletypes = {
-    "": ("", None),       # only when using unbundle on ssh and old http servers
-                          # since the unification ssh accepts a header but there
-                          # is no capability signaling it.
-    "HG20": (), # special-cased below
-    "HG10UN": ("HG10UN", None),
-    "HG10BZ": ("HG10", 'BZ'),
-    "HG10GZ": ("HG10GZ", 'GZ'),
-}
-
-# hgweb uses this list to communicate its preferred type
-bundlepriority = ['HG10GZ', 'HG10BZ', 'HG10UN']
-
 def writechunks(ui, chunks, filename, vfs=None):
     """Write chunks to a file and return its filename.
 
@@ -125,49 +112,6 @@
             else:
                 os.unlink(cleanup)
 
-def writebundle(ui, cg, filename, bundletype, vfs=None, compression=None):
-    """Write a bundle file and return its filename.
-
-    Existing files will not be overwritten.
-    If no filename is specified, a temporary file is created.
-    bz2 compression can be turned off.
-    The bundle file will be deleted in case of errors.
-    """
-
-    if bundletype == "HG20":
-        from . import bundle2
-        bundle = bundle2.bundle20(ui)
-        bundle.setcompression(compression)
-        part = bundle.newpart('changegroup', data=cg.getchunks())
-        part.addparam('version', cg.version)
-        chunkiter = bundle.getchunks()
-    else:
-        # compression argument is only for the bundle2 case
-        assert compression is None
-        if cg.version != '01':
-            raise error.Abort(_('old bundle types only supports v1 '
-                                'changegroups'))
-        header, comp = bundletypes[bundletype]
-        if comp not in util.compressors:
-            raise error.Abort(_('unknown stream compression type: %s')
-                              % comp)
-        z = util.compressors[comp]()
-        subchunkiter = cg.getchunks()
-        def chunkiter():
-            yield header
-            for chunk in subchunkiter:
-                yield z.compress(chunk)
-            yield z.flush()
-        chunkiter = chunkiter()
-
-    # parse the changegroup data, otherwise we will block
-    # in case of sshrepo because we don't know the end of the stream
-
-    # 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
-    return writechunks(ui, chunkiter, filename, vfs=vfs)
-
 class cg1unpacker(object):
     """Unpacker for cg1 changegroup streams.
 
--- a/mercurial/commands.py	Mon Mar 28 17:16:00 2016 -0500
+++ b/mercurial/commands.py	Mon Mar 28 14:41:29 2016 -0700
@@ -1434,8 +1434,7 @@
         assert cgversion == '02'
         bversion = 'HG20'
 
-
-    changegroup.writebundle(ui, cg, fname, bversion, compression=bcompression)
+    bundle2.writebundle(ui, cg, fname, bversion, compression=bcompression)
 
 @command('cat',
     [('o', 'output', '',
@@ -2482,9 +2481,9 @@
               'gzip': 'HG10GZ',
               'bundle2': 'HG20'}
     bundletype = btypes.get(bundletype)
-    if bundletype not in changegroup.bundletypes:
+    if bundletype not in bundle2.bundletypes:
         raise error.Abort(_('unknown bundle type specified with --type'))
-    changegroup.writebundle(ui, bundle, bundlepath, bundletype)
+    bundle2.writebundle(ui, bundle, bundlepath, bundletype)
 
 @command('debugignore', [], '[FILE]')
 def debugignore(ui, repo, *files, **opts):
--- a/mercurial/httppeer.py	Mon Mar 28 17:16:00 2016 -0500
+++ b/mercurial/httppeer.py	Mon Mar 28 14:41:29 2016 -0700
@@ -20,7 +20,7 @@
 from .i18n import _
 from .node import nullid
 from . import (
-    changegroup,
+    bundle2,
     error,
     httpconnection,
     statichttprepo,
@@ -222,11 +222,11 @@
             # bundles.
             types = [""]
         for x in types:
-            if x in changegroup.bundletypes:
+            if x in bundle2.bundletypes:
                 type = x
                 break
 
-        tempname = changegroup.writebundle(self.ui, cg, None, type)
+        tempname = bundle2.writebundle(self.ui, cg, None, type)
         fp = httpconnection.httpsendfile(self.ui, tempname, "rb")
         headers = {'Content-Type': 'application/mercurial-0.1'}
 
--- a/mercurial/repair.py	Mon Mar 28 17:16:00 2016 -0500
+++ b/mercurial/repair.py	Mon Mar 28 14:41:29 2016 -0700
@@ -46,7 +46,7 @@
         bundletype = "HG10BZ"
     else:
         bundletype = "HG10UN"
-    return changegroup.writebundle(repo.ui, cg, name, bundletype, vfs,
+    return bundle2.writebundle(repo.ui, cg, name, bundletype, vfs,
                                    compression=comp)
 
 def _collectfiles(repo, striprev):
--- a/mercurial/wireproto.py	Mon Mar 28 17:16:00 2016 -0500
+++ b/mercurial/wireproto.py	Mon Mar 28 14:41:29 2016 -0700
@@ -685,7 +685,7 @@
     if repo.ui.configbool('experimental', 'bundle2-advertise', True):
         capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
         caps.append('bundle2=' + urllib.quote(capsblob))
-    caps.append('unbundle=%s' % ','.join(changegroupmod.bundlepriority))
+    caps.append('unbundle=%s' % ','.join(bundle2.bundlepriority))
     caps.append(
         'httpheader=%d' % repo.ui.configint('server', 'maxhttpheaderlen', 1024))
     if repo.ui.configbool('experimental', 'httppostargs', False):