changegroup: move chunk extraction into a getchunks method of unbundle10
authorPierre-Yves David <pierre-yves.david@fb.com>
Thu, 10 Apr 2014 13:19:00 -0700
changeset 20999 1e28ec9744bf
parent 20998 93a3c5b58635
child 21000 4cae06ae1562
changegroup: move chunk extraction into a getchunks method of unbundle10 This code used to be in `writebundle` only. We needs to make it more broadly available for bundle2. The "changegroup" bundle2 part has to retrieve the binary content of changegroup stream. We moved the chunks retrieving code into the `unbundle10` object directly and the `writebundle` code is now using that. This split is useful for bundle2 purpose, we want to be able to easily stream changegroup content in a part. To keep thing simples, we kept compression out of the new methods. If it make more sense in the future, compression may get included in this function too.
mercurial/changegroup.py
--- a/mercurial/changegroup.py	Tue Mar 25 15:05:11 2014 -0700
+++ b/mercurial/changegroup.py	Thu Apr 10 13:19:00 2014 -0700
@@ -91,23 +91,8 @@
         # 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
-        empty = False
-        count = 0
-        while not empty or count <= 2:
-            empty = True
-            count += 1
-            while True:
-                chunk = getchunk(cg)
-                if not chunk:
-                    break
-                empty = False
-                fh.write(z.compress(chunkheader(len(chunk))))
-                pos = 0
-                while pos < len(chunk):
-                    next = pos + 2**20
-                    fh.write(z.compress(chunk[pos:next]))
-                    pos = next
-            fh.write(z.compress(closechunk()))
+        for chunk in cg.getchunks():
+            fh.write(z.compress(chunk))
         fh.write(z.flush())
         cleanup = None
         return filename
@@ -202,6 +187,34 @@
         return {'node': node, 'p1': p1, 'p2': p2, 'cs': cs,
                 'deltabase': deltabase, 'delta': delta}
 
+    def getchunks(self):
+        """returns all the chunks contains in the bundle
+
+        Used when you need to forward the binary stream to a file or another
+        network API. To do so, it parse the changegroup data, otherwise it will
+        block in case of sshrepo because it 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
+        empty = False
+        count = 0
+        while not empty or count <= 2:
+            empty = True
+            count += 1
+            while True:
+                chunk = getchunk(self)
+                if not chunk:
+                    break
+                empty = False
+                yield chunkheader(len(chunk))
+                pos = 0
+                while pos < len(chunk):
+                    next = pos + 2**20
+                    yield chunk[pos:next]
+                    pos = next
+            yield closechunk()
+
 class headerlessfixup(object):
     def __init__(self, fh, h):
         self._h = h