diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -3371,17 +3371,6 @@ class localrepository: Intended for use by strip and rollback, so there's a common place for anything that has to be done after destroying history. """ - # When one tries to: - # 1) destroy nodes thus calling this method (e.g. strip) - # 2) use phasecache somewhere (e.g. commit) - # - # then 2) will fail because the phasecache contains nodes that were - # removed. We can either remove phasecache from the filecache, - # causing it to reload next time it is accessed, or simply filter - # the removed nodes now and write the updated cache. - self._phasecache.filterunknown(self) - self._phasecache.write() - # refresh all repository caches self.updatecaches() diff --git a/mercurial/phases.py b/mercurial/phases.py --- a/mercurial/phases.py +++ b/mercurial/phases.py @@ -702,6 +702,24 @@ class phasecache: return True return False + def register_strip( + self, + repo: "localrepo.localrepository", + tr, + strip_rev: int, + ): + """announce a strip to the phase cache + + Any roots higher than the stripped revision should be dropped. + """ + assert repo.filtername is None + to_rev = repo.changelog.index.rev + for targetphase, nodes in list(self.phaseroots.items()): + filtered = {n for n in nodes if to_rev(n) >= strip_rev} + if filtered: + self._updateroots(targetphase, nodes - filtered, tr) + self.invalidate() + def filterunknown(self, repo: "localrepo.localrepository") -> None: """remove unknown nodes from the phase boundary diff --git a/mercurial/repair.py b/mercurial/repair.py --- a/mercurial/repair.py +++ b/mercurial/repair.py @@ -218,6 +218,7 @@ def strip(ui, repo, nodelist, backup=Tru oldfiles = set(tr._offsetmap.keys()) oldfiles.update(tr._newfiles) + repo._phasecache.register_strip(repo, tr, striprev) tr.startgroup() cl.strip(striprev, tr) stripmanifest(repo, striprev, tr, files) @@ -239,7 +240,6 @@ def strip(ui, repo, nodelist, backup=Tru deleteobsmarkers(repo.obsstore, stripobsidx) del repo.obsstore repo.invalidatevolatilesets() - repo._phasecache.filterunknown(repo) if tmpbundlefile: ui.note(_(b"adding branch\n"))