5 # This software may be used and distributed according to the terms of the |
5 # This software may be used and distributed according to the terms of the |
6 # GNU General Public License version 2 or any later version. |
6 # GNU General Public License version 2 or any later version. |
7 |
7 |
8 from i18n import _ |
8 from i18n import _ |
9 from node import nullrev |
9 from node import nullrev |
10 import mdiff, util |
10 import mdiff, util, dagutil |
11 import struct, os, bz2, zlib, tempfile |
11 import struct, os, bz2, zlib, tempfile |
12 |
12 |
13 _BUNDLE10_DELTA_HEADER = "20s20s20s20s" |
13 _BUNDLE10_DELTA_HEADER = "20s20s20s20s" |
14 |
14 |
15 def readexactly(stream, n): |
15 def readexactly(stream, n): |
229 pass |
229 pass |
230 def start(self, lookup): |
230 def start(self, lookup): |
231 self._lookup = lookup |
231 self._lookup = lookup |
232 def close(self): |
232 def close(self): |
233 return closechunk() |
233 return closechunk() |
|
234 |
234 def fileheader(self, fname): |
235 def fileheader(self, fname): |
235 return chunkheader(len(fname)) + fname |
236 return chunkheader(len(fname)) + fname |
|
237 |
|
238 def group(self, nodelist, revlog, reorder=None): |
|
239 """Calculate a delta group, yielding a sequence of changegroup chunks |
|
240 (strings). |
|
241 |
|
242 Given a list of changeset revs, return a set of deltas and |
|
243 metadata corresponding to nodes. The first delta is |
|
244 first parent(nodelist[0]) -> nodelist[0], the receiver is |
|
245 guaranteed to have this parent as it has all history before |
|
246 these changesets. In the case firstparent is nullrev the |
|
247 changegroup starts with a full revision. |
|
248 """ |
|
249 |
|
250 # if we don't have any revisions touched by these changesets, bail |
|
251 if len(nodelist) == 0: |
|
252 yield self.close() |
|
253 return |
|
254 |
|
255 # for generaldelta revlogs, we linearize the revs; this will both be |
|
256 # much quicker and generate a much smaller bundle |
|
257 if (revlog._generaldelta and reorder is not False) or reorder: |
|
258 dag = dagutil.revlogdag(revlog) |
|
259 revs = set(revlog.rev(n) for n in nodelist) |
|
260 revs = dag.linearize(revs) |
|
261 else: |
|
262 revs = sorted([revlog.rev(n) for n in nodelist]) |
|
263 |
|
264 # add the parent of the first rev |
|
265 p = revlog.parentrevs(revs[0])[0] |
|
266 revs.insert(0, p) |
|
267 |
|
268 # build deltas |
|
269 for r in xrange(len(revs) - 1): |
|
270 prev, curr = revs[r], revs[r + 1] |
|
271 for c in self.revchunk(revlog, curr, prev): |
|
272 yield c |
|
273 |
|
274 yield self.close() |
|
275 |
|
276 |
236 def revchunk(self, revlog, rev, prev): |
277 def revchunk(self, revlog, rev, prev): |
237 node = revlog.node(rev) |
278 node = revlog.node(rev) |
238 p1, p2 = revlog.parentrevs(rev) |
279 p1, p2 = revlog.parentrevs(rev) |
239 base = prev |
280 base = prev |
240 |
281 |