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