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.
--- 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