Mercurial > hg
comparison mercurial/changegroup.py @ 20999:1e28ec9744bf
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.
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Thu, 10 Apr 2014 13:19:00 -0700 |
parents | 5b58714e97ed |
children | 7ca4f2049d3b |
comparison
equal
deleted
inserted
replaced
20998:93a3c5b58635 | 20999:1e28ec9744bf |
---|---|
89 # in case of sshrepo because we don't know the end of the stream | 89 # in case of sshrepo because we don't know the end of the stream |
90 | 90 |
91 # an empty chunkgroup is the end of the changegroup | 91 # an empty chunkgroup is the end of the changegroup |
92 # a changegroup has at least 2 chunkgroups (changelog and manifest). | 92 # a changegroup has at least 2 chunkgroups (changelog and manifest). |
93 # after that, an empty chunkgroup is the end of the changegroup | 93 # after that, an empty chunkgroup is the end of the changegroup |
94 empty = False | 94 for chunk in cg.getchunks(): |
95 count = 0 | 95 fh.write(z.compress(chunk)) |
96 while not empty or count <= 2: | |
97 empty = True | |
98 count += 1 | |
99 while True: | |
100 chunk = getchunk(cg) | |
101 if not chunk: | |
102 break | |
103 empty = False | |
104 fh.write(z.compress(chunkheader(len(chunk)))) | |
105 pos = 0 | |
106 while pos < len(chunk): | |
107 next = pos + 2**20 | |
108 fh.write(z.compress(chunk[pos:next])) | |
109 pos = next | |
110 fh.write(z.compress(closechunk())) | |
111 fh.write(z.flush()) | 96 fh.write(z.flush()) |
112 cleanup = None | 97 cleanup = None |
113 return filename | 98 return filename |
114 finally: | 99 finally: |
115 if fh is not None: | 100 if fh is not None: |
199 header = struct.unpack(self.deltaheader, headerdata) | 184 header = struct.unpack(self.deltaheader, headerdata) |
200 delta = readexactly(self._stream, l - self.deltaheadersize) | 185 delta = readexactly(self._stream, l - self.deltaheadersize) |
201 node, p1, p2, deltabase, cs = self._deltaheader(header, prevnode) | 186 node, p1, p2, deltabase, cs = self._deltaheader(header, prevnode) |
202 return {'node': node, 'p1': p1, 'p2': p2, 'cs': cs, | 187 return {'node': node, 'p1': p1, 'p2': p2, 'cs': cs, |
203 'deltabase': deltabase, 'delta': delta} | 188 'deltabase': deltabase, 'delta': delta} |
189 | |
190 def getchunks(self): | |
191 """returns all the chunks contains in the bundle | |
192 | |
193 Used when you need to forward the binary stream to a file or another | |
194 network API. To do so, it parse the changegroup data, otherwise it will | |
195 block in case of sshrepo because it don't know the end of the stream. | |
196 """ | |
197 # an empty chunkgroup is the end of the changegroup | |
198 # a changegroup has at least 2 chunkgroups (changelog and manifest). | |
199 # after that, an empty chunkgroup is the end of the changegroup | |
200 empty = False | |
201 count = 0 | |
202 while not empty or count <= 2: | |
203 empty = True | |
204 count += 1 | |
205 while True: | |
206 chunk = getchunk(self) | |
207 if not chunk: | |
208 break | |
209 empty = False | |
210 yield chunkheader(len(chunk)) | |
211 pos = 0 | |
212 while pos < len(chunk): | |
213 next = pos + 2**20 | |
214 yield chunk[pos:next] | |
215 pos = next | |
216 yield closechunk() | |
204 | 217 |
205 class headerlessfixup(object): | 218 class headerlessfixup(object): |
206 def __init__(self, fh, h): | 219 def __init__(self, fh, h): |
207 self._h = h | 220 self._h = h |
208 self._fh = fh | 221 self._fh = fh |