Mercurial > hg-stable
changeset 35840:33275ab5e837 stable
revlog: do not use delta for lfs revisions
This is similar to what we have done for changegroups. It is needed to make
sure the delta application code path can assume deltas are always against
vanilla (ex. non-LFS) rawtext so the next fix becomes possible.
Differential Revision: https://phab.mercurial-scm.org/D2068
author | Jun Wu <quark@fb.com> |
---|---|
date | Tue, 13 Feb 2018 11:35:32 -0800 |
parents | d031609b3cb7 |
children | 369aadf7a326 |
files | mercurial/revlog.py tests/test-lfs-bundle.t tests/test-revlog-raw.py |
diffstat | 3 files changed, 22 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/revlog.py Tue Feb 06 19:08:25 2018 -0800 +++ b/mercurial/revlog.py Tue Feb 13 11:35:32 2018 -0800 @@ -407,6 +407,9 @@ for candidaterevs in self._getcandidaterevs(p1, p2, cachedelta): nominateddeltas = [] for candidaterev in candidaterevs: + # no delta for rawtext-changing revs (see "candelta" for why) + if revlog.flags(candidaterev) & REVIDX_RAWTEXT_CHANGING_FLAGS: + continue candidatedelta = self._builddeltainfo(revinfo, candidaterev, fh) if revlog._isgooddeltainfo(candidatedelta, revinfo.textlen): nominateddeltas.append(candidatedelta) @@ -2090,7 +2093,14 @@ deltacomputer = _deltacomputer(self) revinfo = _revisioninfo(node, p1, p2, btext, textlen, cachedelta, flags) - deltainfo = deltacomputer.finddeltainfo(revinfo, fh) + + # no delta for flag processor revision (see "candelta" for why) + # not calling candelta since only one revision needs test, also to + # avoid overhead fetching flags again. + if flags & REVIDX_RAWTEXT_CHANGING_FLAGS: + deltainfo = None + else: + deltainfo = deltacomputer.finddeltainfo(revinfo, fh) if deltainfo is not None: base = deltainfo.base
--- a/tests/test-lfs-bundle.t Tue Feb 06 19:08:25 2018 -0800 +++ b/tests/test-lfs-bundle.t Tue Feb 13 11:35:32 2018 -0800 @@ -90,10 +90,7 @@ ---- Applying src-normal.bundle to dst-normal ---- OK ---- Applying src-normal.bundle to dst-lfs ---- - X@2: unpacking bcc7d23fa6b7: integrity check failed on data/X.i:2 - Y@2: unpacking 46017a6640e7: integrity check failed on data/Y.i:2 - 2 integrity errors encountered! - (first damaged changeset appears to be 2) + CRASHED ---- Applying src-lfs.bundle to dst-normal ---- OK ---- Applying src-lfs.bundle to dst-lfs ----
--- a/tests/test-revlog-raw.py Tue Feb 06 19:08:25 2018 -0800 +++ b/tests/test-revlog-raw.py Tue Feb 13 11:35:32 2018 -0800 @@ -114,6 +114,8 @@ else: # suboptimal deltaparent deltaparent = min(0, parentrev) + if not rlog.candelta(deltaparent, r): + deltaparent = -1 return {'node': rlog.node(r), 'p1': pnode, 'p2': node.nullid, 'cs': rlog.node(rlog.linkrev(r)), 'flags': rlog.flags(r), 'deltabase': rlog.node(deltaparent), @@ -151,12 +153,14 @@ for r in rlog: p1 = rlog.node(r - 1) p2 = node.nullid - if r == 0: + if r == 0 or (rlog.flags(r) & revlog.REVIDX_EXTSTORED): text = rlog.revision(r, raw=True) cachedelta = None else: - # deltaparent is more interesting if it has the EXTSTORED flag. - deltaparent = max([0] + [p for p in range(r - 2) if rlog.flags(p)]) + # deltaparent cannot have EXTSTORED flag. + deltaparent = max([-1] + + [p for p in range(r) + if rlog.flags(p) & revlog.REVIDX_EXTSTORED == 0]) text = None cachedelta = (deltaparent, rlog.revdiff(deltaparent, r)) flags = rlog.flags(r) @@ -262,8 +266,9 @@ result.append((text, rawtext)) # Verify flags like isdelta, isext work as expected - if bool(rlog.deltaparent(rev) > -1) != isdelta: - abort('rev %d: isdelta is ineffective' % rev) + # isdelta can be overridden to False if this or p1 has isext set + if bool(rlog.deltaparent(rev) > -1) and not isdelta: + abort('rev %d: isdelta is unexpected' % rev) if bool(rlog.flags(rev)) != isext: abort('rev %d: isext is ineffective' % rev) return result