diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -233,7 +233,8 @@ # no new manifest will be created and the manifest group will # be empty during the pull self.manifestheader() - repo.manifestlog._revlog.addgroup(self, revmap, trp) + deltas = self.deltaiter(revmap) + repo.manifestlog._revlog.addgroup(deltas, trp) repo.ui.progress(_('manifests'), None) self.callback = None @@ -295,7 +296,8 @@ efiles.update(cl.readfiles(node)) self.changelogheader() - cgnodes = cl.addgroup(self, csmap, trp, addrevisioncb=onchangelog) + deltas = self.deltaiter(csmap) + cgnodes = cl.addgroup(deltas, trp, addrevisioncb=onchangelog) efiles = len(efiles) if not cgnodes: @@ -416,6 +418,27 @@ ret = deltaheads + 1 return ret + def deltaiter(self, linkmapper): + """ + returns an iterator of the deltas in this changegroup + + Useful for passing to the underlying storage system to be stored. + """ + chain = None + for chunkdata in iter(lambda: self.deltachunk(chain), {}): + node = chunkdata['node'] + p1 = chunkdata['p1'] + p2 = chunkdata['p2'] + cs = chunkdata['cs'] + deltabase = chunkdata['deltabase'] + delta = chunkdata['delta'] + flags = chunkdata['flags'] + + link = linkmapper(cs) + chain = node + + yield (node, p1, p2, link, deltabase, delta, flags) + class cg2unpacker(cg1unpacker): """Unpacker for cg2 streams. @@ -456,7 +479,8 @@ d = chunkdata["filename"] repo.ui.debug("adding %s revisions\n" % d) dirlog = repo.manifestlog._revlog.dirlog(d) - if not dirlog.addgroup(self, revmap, trp): + deltas = self.deltaiter(revmap) + if not dirlog.addgroup(deltas, trp): raise error.Abort(_("received dir revlog group is empty")) class headerlessfixup(object): @@ -985,7 +1009,8 @@ fl = repo.file(f) o = len(fl) try: - if not fl.addgroup(source, revmap, trp): + deltas = source.deltaiter(revmap) + if not fl.addgroup(deltas, trp): raise error.Abort(_("received file revlog group is empty")) except error.CensoredBaseError as e: raise error.Abort(_("received delta base is censored: %s") % e) diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -1872,7 +1872,7 @@ ifh.write(data[1]) self.checkinlinesize(transaction, ifh) - def addgroup(self, cg, linkmapper, transaction, addrevisioncb=None): + def addgroup(self, deltas, transaction, addrevisioncb=None): """ add a delta group @@ -1905,22 +1905,14 @@ ifh.flush() try: # loop through our set of deltas - chain = None - for chunkdata in iter(lambda: cg.deltachunk(chain), {}): - node = chunkdata['node'] - p1 = chunkdata['p1'] - p2 = chunkdata['p2'] - cs = chunkdata['cs'] - deltabase = chunkdata['deltabase'] - delta = chunkdata['delta'] - flags = chunkdata['flags'] or REVIDX_DEFAULT_FLAGS + for data in deltas: + node, p1, p2, link, deltabase, delta, flags = data + flags = flags or REVIDX_DEFAULT_FLAGS nodes.append(node) - link = linkmapper(cs) if node in self.nodemap: # this can happen if two branches make the same change - chain = node continue for p in (p1, p2): @@ -1954,13 +1946,13 @@ # We're only using addgroup() in the context of changegroup # generation so the revision data can always be handled as raw # by the flagprocessor. - chain = self._addrevision(node, None, transaction, link, - p1, p2, flags, (baserev, delta), - ifh, dfh, - alwayscache=bool(addrevisioncb)) + self._addrevision(node, None, transaction, link, + p1, p2, flags, (baserev, delta), + ifh, dfh, + alwayscache=bool(addrevisioncb)) if addrevisioncb: - addrevisioncb(self, chain) + addrevisioncb(self, node) if not dfh and not self._inline: # addrevision switched from inline to conventional diff --git a/tests/test-revlog-raw.py b/tests/test-revlog-raw.py --- a/tests/test-revlog-raw.py +++ b/tests/test-revlog-raw.py @@ -119,11 +119,28 @@ 'deltabase': rlog.node(deltaparent), 'delta': rlog.revdiff(deltaparent, r)} + def deltaiter(self, linkmapper): + chain = None + for chunkdata in iter(lambda: self.deltachunk(chain), {}): + node = chunkdata['node'] + p1 = chunkdata['p1'] + p2 = chunkdata['p2'] + cs = chunkdata['cs'] + deltabase = chunkdata['deltabase'] + delta = chunkdata['delta'] + flags = chunkdata['flags'] + + link = linkmapper(cs) + chain = node + + yield (node, p1, p2, link, deltabase, delta, flags) + def linkmap(lnode): return rlog.rev(lnode) dlog = newrevlog(destname, recreate=True) - dlog.addgroup(dummychangegroup(), linkmap, tr) + dummydeltas = dummychangegroup().deltaiter(linkmap) + dlog.addgroup(dummydeltas, tr) return dlog def lowlevelcopy(rlog, tr, destname=b'_destrevlog.i'):