Mercurial > public > mercurial-scm > hg
comparison mercurial/changegroup.py @ 34291:1db9abf407c5
revlog: add revmap back to revlog.addgroup
The recent c8b6ed51386b patch removed the linkmapper argument from addgroup, as
part of trying to make addgroup more agnostic from the changegroup format. It
turns out that the changegroup can't resolve linkrevs while iterating over the
deltas, because applying the deltas might affect the linkrev resolution. For
example, when applying a series of changelog entries, the linkmapper just
returns len(cl). If we're iterating over the deltas without applying them to the
changelog, this results in incorrect linkrevs. This was caught by the hgsql
extension, which reads the revisions before applying them.
The fix is to return linknodes as part of the delta iterator, and let the
consumer choose what to do.
Differential Revision: https://phab.mercurial-scm.org/D730
author | Durham Goode <durham@fb.com> |
---|---|
date | Wed, 20 Sep 2017 09:22:22 -0700 |
parents | 2844c4bd5a39 |
children | 05131c963767 |
comparison
equal
deleted
inserted
replaced
34290:4f969b9e0cf5 | 34291:1db9abf407c5 |
---|---|
243 # no need to check for empty manifest group here: | 243 # no need to check for empty manifest group here: |
244 # if the result of the merge of 1 and 2 is the same in 3 and 4, | 244 # if the result of the merge of 1 and 2 is the same in 3 and 4, |
245 # no new manifest will be created and the manifest group will | 245 # no new manifest will be created and the manifest group will |
246 # be empty during the pull | 246 # be empty during the pull |
247 self.manifestheader() | 247 self.manifestheader() |
248 deltas = self.deltaiter(revmap) | 248 deltas = self.deltaiter() |
249 repo.manifestlog._revlog.addgroup(deltas, trp) | 249 repo.manifestlog._revlog.addgroup(deltas, revmap, trp) |
250 repo.ui.progress(_('manifests'), None) | 250 repo.ui.progress(_('manifests'), None) |
251 self.callback = None | 251 self.callback = None |
252 | 252 |
253 def apply(self, repo, tr, srctype, url, targetphase=phases.draft, | 253 def apply(self, repo, tr, srctype, url, targetphase=phases.draft, |
254 expectedtotal=None): | 254 expectedtotal=None): |
306 efiles = set() | 306 efiles = set() |
307 def onchangelog(cl, node): | 307 def onchangelog(cl, node): |
308 efiles.update(cl.readfiles(node)) | 308 efiles.update(cl.readfiles(node)) |
309 | 309 |
310 self.changelogheader() | 310 self.changelogheader() |
311 deltas = self.deltaiter(csmap) | 311 deltas = self.deltaiter() |
312 cgnodes = cl.addgroup(deltas, trp, addrevisioncb=onchangelog) | 312 cgnodes = cl.addgroup(deltas, csmap, trp, addrevisioncb=onchangelog) |
313 efiles = len(efiles) | 313 efiles = len(efiles) |
314 | 314 |
315 if not cgnodes: | 315 if not cgnodes: |
316 repo.ui.develwarn('applied empty changegroup', | 316 repo.ui.develwarn('applied empty changegroup', |
317 config='empty-changegroup') | 317 config='empty-changegroup') |
428 ret = deltaheads - 1 | 428 ret = deltaheads - 1 |
429 else: | 429 else: |
430 ret = deltaheads + 1 | 430 ret = deltaheads + 1 |
431 return ret | 431 return ret |
432 | 432 |
433 def deltaiter(self, linkmapper): | 433 def deltaiter(self): |
434 """ | 434 """ |
435 returns an iterator of the deltas in this changegroup | 435 returns an iterator of the deltas in this changegroup |
436 | 436 |
437 Useful for passing to the underlying storage system to be stored. | 437 Useful for passing to the underlying storage system to be stored. |
438 """ | 438 """ |
444 cs = chunkdata['cs'] | 444 cs = chunkdata['cs'] |
445 deltabase = chunkdata['deltabase'] | 445 deltabase = chunkdata['deltabase'] |
446 delta = chunkdata['delta'] | 446 delta = chunkdata['delta'] |
447 flags = chunkdata['flags'] | 447 flags = chunkdata['flags'] |
448 | 448 |
449 link = linkmapper(cs) | |
450 chain = node | 449 chain = node |
451 | 450 |
452 yield (node, p1, p2, link, deltabase, delta, flags) | 451 yield (node, p1, p2, cs, deltabase, delta, flags) |
453 | 452 |
454 class cg2unpacker(cg1unpacker): | 453 class cg2unpacker(cg1unpacker): |
455 """Unpacker for cg2 streams. | 454 """Unpacker for cg2 streams. |
456 | 455 |
457 cg2 streams add support for generaldelta, so the delta header | 456 cg2 streams add support for generaldelta, so the delta header |
489 for chunkdata in iter(self.filelogheader, {}): | 488 for chunkdata in iter(self.filelogheader, {}): |
490 # If we get here, there are directory manifests in the changegroup | 489 # If we get here, there are directory manifests in the changegroup |
491 d = chunkdata["filename"] | 490 d = chunkdata["filename"] |
492 repo.ui.debug("adding %s revisions\n" % d) | 491 repo.ui.debug("adding %s revisions\n" % d) |
493 dirlog = repo.manifestlog._revlog.dirlog(d) | 492 dirlog = repo.manifestlog._revlog.dirlog(d) |
494 deltas = self.deltaiter(revmap) | 493 deltas = self.deltaiter() |
495 if not dirlog.addgroup(deltas, trp): | 494 if not dirlog.addgroup(deltas, revmap, trp): |
496 raise error.Abort(_("received dir revlog group is empty")) | 495 raise error.Abort(_("received dir revlog group is empty")) |
497 | 496 |
498 class headerlessfixup(object): | 497 class headerlessfixup(object): |
499 def __init__(self, fh, h): | 498 def __init__(self, fh, h): |
500 self._h = h | 499 self._h = h |
981 repo.ui.progress(_('files'), files, unit=_('files'), | 980 repo.ui.progress(_('files'), files, unit=_('files'), |
982 total=expectedfiles) | 981 total=expectedfiles) |
983 fl = repo.file(f) | 982 fl = repo.file(f) |
984 o = len(fl) | 983 o = len(fl) |
985 try: | 984 try: |
986 deltas = source.deltaiter(revmap) | 985 deltas = source.deltaiter() |
987 if not fl.addgroup(deltas, trp): | 986 if not fl.addgroup(deltas, revmap, trp): |
988 raise error.Abort(_("received file revlog group is empty")) | 987 raise error.Abort(_("received file revlog group is empty")) |
989 except error.CensoredBaseError as e: | 988 except error.CensoredBaseError as e: |
990 raise error.Abort(_("received delta base is censored: %s") % e) | 989 raise error.Abort(_("received delta base is censored: %s") % e) |
991 revisions += len(fl) - o | 990 revisions += len(fl) - o |
992 if f in needfiles: | 991 if f in needfiles: |