diff -r d6d0f1ed8ebb -r 4cfdec944edf mercurial/changegroup.py --- a/mercurial/changegroup.py Fri May 10 20:37:41 2013 +0200 +++ b/mercurial/changegroup.py Fri May 10 21:03:01 2013 +0200 @@ -7,7 +7,7 @@ from i18n import _ from node import nullrev -import mdiff, util +import mdiff, util, dagutil import struct, os, bz2, zlib, tempfile _BUNDLE10_DELTA_HEADER = "20s20s20s20s" @@ -231,8 +231,49 @@ self._lookup = lookup def close(self): return closechunk() + def fileheader(self, fname): return chunkheader(len(fname)) + fname + + def group(self, nodelist, revlog, reorder=None): + """Calculate a delta group, yielding a sequence of changegroup chunks + (strings). + + Given a list of changeset revs, return a set of deltas and + metadata corresponding to nodes. The first delta is + first parent(nodelist[0]) -> nodelist[0], the receiver is + guaranteed to have this parent as it has all history before + these changesets. In the case firstparent is nullrev the + changegroup starts with a full revision. + """ + + # if we don't have any revisions touched by these changesets, bail + if len(nodelist) == 0: + yield self.close() + return + + # for generaldelta revlogs, we linearize the revs; this will both be + # much quicker and generate a much smaller bundle + if (revlog._generaldelta and reorder is not False) or reorder: + dag = dagutil.revlogdag(revlog) + revs = set(revlog.rev(n) for n in nodelist) + revs = dag.linearize(revs) + else: + revs = sorted([revlog.rev(n) for n in nodelist]) + + # add the parent of the first rev + p = revlog.parentrevs(revs[0])[0] + revs.insert(0, p) + + # build deltas + for r in xrange(len(revs) - 1): + prev, curr = revs[r], revs[r + 1] + for c in self.revchunk(revlog, curr, prev): + yield c + + yield self.close() + + def revchunk(self, revlog, rev, prev): node = revlog.node(rev) p1, p2 = revlog.parentrevs(rev)