diff --git a/mercurial/changelog.py b/mercurial/changelog.py --- a/mercurial/changelog.py +++ b/mercurial/changelog.py @@ -599,7 +599,7 @@ l = [hex(manifest), user, parseddate] + sortedfiles + [b"", desc] text = b"\n".join(l) return self.addrevision( - text, transaction, len(self), p1, p2, sidedata=sidedata + text, transaction, len(self), p1, p2, sidedata=sidedata, flags=flags ) def branchinfo(self, rev): diff --git a/mercurial/copies.py b/mercurial/copies.py --- a/mercurial/copies.py +++ b/mercurial/copies.py @@ -24,6 +24,8 @@ from .utils import stringutil +from .revlogutils import flagutil + def _filter(src, dst, t): """filters out invalid copies after chaining""" @@ -179,6 +181,9 @@ """ cl = repo.changelog parents = cl.parentrevs + flags = cl.flags + + HASCOPIESINFO = flagutil.REVIDX_HASCOPIESINFO changelogrevision = cl.changelogrevision @@ -213,7 +218,10 @@ e = merge_caches.pop(rev, None) if e is not None: return e - value = (p1, p2, changelogrevision(rev).changes) + changes = None + if flags(rev) & HASCOPIESINFO: + changes = changelogrevision(rev).changes + value = (p1, p2, changes) if p1 != node.nullrev and p2 != node.nullrev: # XXX some case we over cache, IGNORE merge_caches[rev] = value @@ -293,13 +301,16 @@ copies = {} for i, c in enumerate(children[r]): p1, p2, changes = revinfo(c) + childcopies = {} if r == p1: parent = 1 - childcopies = changes.copied_from_p1 + if changes is not None: + childcopies = changes.copied_from_p1 else: assert r == p2 parent = 2 - childcopies = changes.copied_from_p2 + if changes is not None: + childcopies = changes.copied_from_p2 if not alwaysmatch: childcopies = { dst: src for dst, src in childcopies.items() if match(dst) @@ -313,14 +324,15 @@ source = prev[1] newcopies[dest] = (c, source) assert newcopies is not copies - for f in changes.removed: - if f in newcopies: - if newcopies is copies: - # copy on write to avoid affecting potential other - # branches. when there are no other branches, this - # could be avoided. - newcopies = copies.copy() - newcopies[f] = (c, None) + if changes is not None: + for f in changes.removed: + if f in newcopies: + if newcopies is copies: + # copy on write to avoid affecting potential other + # branches. when there are no other branches, this + # could be avoided. + newcopies = copies.copy() + newcopies[f] = (c, None) othercopies = all_copies.get(c) if othercopies is None: all_copies[c] = newcopies @@ -373,13 +385,21 @@ # than the branch point or there is a merge if new_tt == other_tt: minor[dest] = value - elif value[1] is None and dest in changes.salvaged: + elif ( + changes is not None + and value[1] is None + and dest in changes.salvaged + ): pass - elif other[1] is None and dest in changes.salvaged: + elif ( + changes is not None + and other[1] is None + and dest in changes.salvaged + ): minor[dest] = value elif not isancestor(new_tt, other_tt): minor[dest] = value - elif dest in changes.merged: + elif changes is not None and dest in changes.merged: minor[dest] = value