Mercurial > hg-stable
changeset 23181:832b7ef275c8
changegroup: introduce cg2packer/unpacker
cg2 supports generaldelta in changegroups, to be used in bundle2.
Since generaldelta is handled directly in cg2, reordering is switched
off by default.
author | Sune Foldager <cryo@cyanite.org> |
---|---|
date | Fri, 17 Oct 2014 14:41:11 +0200 |
parents | 116b80d63815 |
children | 9b6c3947b4a7 |
files | mercurial/changegroup.py |
diffstat | 1 files changed, 36 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/changegroup.py Fri Oct 17 12:19:24 2014 -0700 +++ b/mercurial/changegroup.py Fri Oct 17 14:41:11 2014 +0200 @@ -13,6 +13,7 @@ import discovery, error, phases, branchmap _CHANGEGROUPV1_DELTA_HEADER = "20s20s20s20s" +_CHANGEGROUPV2_DELTA_HEADER = "20s20s20s20s20s" def readexactly(stream, n): '''read n bytes from stream.read and abort if less was available''' @@ -215,6 +216,14 @@ pos = next yield closechunk() +class cg2unpacker(cg1unpacker): + deltaheader = _CHANGEGROUPV2_DELTA_HEADER + deltaheadersize = struct.calcsize(deltaheader) + + def _deltaheader(self, headertuple, prevnode): + node, p1, p2, deltabase, cs = headertuple + return node, p1, p2, deltabase, cs + class headerlessfixup(object): def __init__(self, fh, h): self._h = h @@ -410,10 +419,13 @@ reorder=reorder): yield chunk + def deltaparent(self, revlog, rev, p1, p2, prev): + return prev + def revchunk(self, revlog, rev, prev, linknode): node = revlog.node(rev) p1, p2 = revlog.parentrevs(rev) - base = prev + base = self.deltaparent(revlog, rev, p1, p2, prev) prefix = '' if base == nullrev: @@ -433,7 +445,29 @@ # do nothing with basenode, it is implicitly the previous one in HG10 return struct.pack(self.deltaheader, node, p1n, p2n, linknode) -packermap = {'01': (cg1packer, cg1unpacker)} +class cg2packer(cg1packer): + + deltaheader = _CHANGEGROUPV2_DELTA_HEADER + + def group(self, nodelist, revlog, lookup, units=None, reorder=None): + if (revlog._generaldelta and reorder is not True): + reorder = False + return cg1packer.group(self, nodelist, revlog, lookup, + units=units, reorder=reorder) + + def deltaparent(self, revlog, rev, p1, p2, prev): + dp = revlog.deltaparent(rev) + # avoid storing full revisions; pick prev in those cases + # also pick prev when we can't be sure remote has dp + if dp == nullrev or (dp != p1 and dp != p2 and dp != prev): + return prev + return dp + + def builddeltaheader(self, node, p1n, p2n, basenode, linknode): + return struct.pack(self.deltaheader, node, p1n, p2n, basenode, linknode) + +packermap = {'01': (cg1packer, cg1unpacker), + '02': (cg2packer, cg2unpacker)} def _changegroupinfo(repo, nodes, source): if repo.ui.verbose or source == 'bundle':