197 |
197 |
198 Used when you need to forward the binary stream to a file or another |
198 Used when you need to forward the binary stream to a file or another |
199 network API. To do so, it parse the changegroup data, otherwise it will |
199 network API. To do so, it parse the changegroup data, otherwise it will |
200 block in case of sshrepo because it don't know the end of the stream. |
200 block in case of sshrepo because it don't know the end of the stream. |
201 """ |
201 """ |
202 # an empty chunkgroup is the end of the changegroup |
202 # For changegroup 1 and 2, we expect 3 parts: changelog, manifestlog, |
203 # a changegroup has at least 2 chunkgroups (changelog and manifest). |
203 # and a list of filelogs. For changegroup 3, we expect 4 parts: |
204 # after that, changegroup versions 1 and 2 have a series of groups |
204 # changelog, manifestlog, a list of tree manifestlogs, and a list of |
205 # with one group per file. changegroup 3 has a series of directory |
205 # filelogs. |
206 # manifests before the files. |
206 # |
207 count = 0 |
207 # Changelog and manifestlog parts are terminated with empty chunks. The |
208 emptycount = 0 |
208 # tree and file parts are a list of entry sections. Each entry section |
209 while emptycount < self._grouplistcount: |
209 # is a series of chunks terminating in an empty chunk. The list of these |
210 empty = True |
210 # entry sections is terminated in yet another empty chunk, so we know |
211 count += 1 |
211 # we've reached the end of the tree/file list when we reach an empty |
|
212 # chunk that was proceeded by no non-empty chunks. |
|
213 |
|
214 parts = 0 |
|
215 while parts < 2 + self._grouplistcount: |
|
216 noentries = True |
212 while True: |
217 while True: |
213 chunk = getchunk(self) |
218 chunk = getchunk(self) |
214 if not chunk: |
219 if not chunk: |
215 if empty and count > 2: |
220 # The first two empty chunks represent the end of the |
216 emptycount += 1 |
221 # changelog and the manifestlog portions. The remaining |
|
222 # empty chunks represent either A) the end of individual |
|
223 # tree or file entries in the file list, or B) the end of |
|
224 # the entire list. It's the end of the entire list if there |
|
225 # were no entries (i.e. noentries is True). |
|
226 if parts < 2: |
|
227 parts += 1 |
|
228 elif noentries: |
|
229 parts += 1 |
217 break |
230 break |
218 empty = False |
231 noentries = False |
219 yield chunkheader(len(chunk)) |
232 yield chunkheader(len(chunk)) |
220 pos = 0 |
233 pos = 0 |
221 while pos < len(chunk): |
234 while pos < len(chunk): |
222 next = pos + 2**20 |
235 next = pos + 2**20 |
223 yield chunk[pos:next] |
236 yield chunk[pos:next] |