# HG changeset patch # User Pierre-Yves David # Date 1708461481 -3600 # Node ID 04111ef08fb0c9350c11a3743d58512a4195b20d # Parent 68289ed170c73a495cfa385dcaecce27a2db7894 phases: always write with a repo In the future change that move the internal representation of phase-roots from node-id to rev-num, we will use a repository to translate revision numbers back to node at write time. Since that future change is quite complicated already, we do this small API change beforehand. diff -r 68289ed170c7 -r 04111ef08fb0 mercurial/bundlerepo.py --- a/mercurial/bundlerepo.py Tue Feb 20 17:18:15 2024 +0100 +++ b/mercurial/bundlerepo.py Tue Feb 20 21:38:01 2024 +0100 @@ -269,7 +269,7 @@ def _write(self, fp): raise NotImplementedError - def _updateroots(self, phase, newroots, tr): + def _updateroots(self, repo, phase, newroots, tr): self._phaseroots[phase] = newroots self.invalidate() self.dirty = True diff -r 68289ed170c7 -r 04111ef08fb0 mercurial/localrepo.py --- a/mercurial/localrepo.py Tue Feb 20 17:18:15 2024 +0100 +++ b/mercurial/localrepo.py Tue Feb 20 21:38:01 2024 +0100 @@ -3363,7 +3363,7 @@ # dirty after committing. Then when we strip, the repo is invalidated, # causing those changes to disappear. if '_phasecache' in vars(self): - self._phasecache.write() + self._phasecache.write(self) @unfilteredmethod def destroyed(self): diff -r 68289ed170c7 -r 04111ef08fb0 mercurial/phases.py --- a/mercurial/phases.py Tue Feb 20 17:18:15 2024 +0100 +++ b/mercurial/phases.py Tue Feb 20 21:38:01 2024 +0100 @@ -103,6 +103,7 @@ import struct import typing +import weakref from typing import ( Any, @@ -367,7 +368,6 @@ self._loadedrevslen = 0 self._phasesets = None self.filterunknown(repo) - self.opener = repo.svfs def hasnonpublicphases(self, repo: "localrepo.localrepository") -> bool: """detect if there are revisions with non-public phase""" @@ -466,7 +466,6 @@ ph = self.__class__(None, None, _load=False) ph._phaseroots = self._phaseroots.copy() ph.dirty = self.dirty - ph.opener = self.opener ph._loadedrevslen = self._loadedrevslen ph._phasesets = self._phasesets return ph @@ -476,7 +475,6 @@ for a in ( '_phaseroots', 'dirty', - 'opener', '_loadedrevslen', '_phasesets', ): @@ -533,27 +531,36 @@ return phase return public - def write(self): + def write(self, repo): if not self.dirty: return - f = self.opener(b'phaseroots', b'w', atomictemp=True, checkambig=True) + f = repo.svfs(b'phaseroots', b'w', atomictemp=True, checkambig=True) try: - self._write(f) + self._write(repo.unfiltered(), f) finally: f.close() - def _write(self, fp): + def _write(self, repo, fp): + assert repo.filtername is None for phase, roots in self._phaseroots.items(): for h in sorted(roots): fp.write(b'%i %s\n' % (phase, hex(h))) self.dirty = False - def _updateroots(self, phase, newroots, tr): + def _updateroots(self, repo, phase, newroots, tr): self._phaseroots[phase] = newroots self.invalidate() self.dirty = True - tr.addfilegenerator(b'phase', (b'phaseroots',), self._write) + assert repo.filtername is None + wrepo = weakref.ref(repo) + + def tr_write(fp): + repo = wrepo() + assert repo is not None + self._write(repo, fp) + + tr.addfilegenerator(b'phase', (b'phaseroots',), tr_write) tr.hookargs[b'phases_moved'] = b'1' def registernew(self, repo, tr, targetphase, revs): @@ -614,7 +621,7 @@ for ctx in repo.set(b'roots((%ln::) - %ld)', olds, affected) } if olds != roots: - self._updateroots(phase, roots, tr) + self._updateroots(repo, phase, roots, tr) # some roots may need to be declared for lower phases delroots.extend(olds - roots) if not dryrun: @@ -697,7 +704,10 @@ finalroots.update(updatedroots) if finalroots != oldroots: self._updateroots( - targetphase, {tonode(rev) for rev in finalroots}, tr + repo, + targetphase, + {tonode(rev) for rev in finalroots}, + tr, ) return True return False @@ -717,7 +727,7 @@ 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._updateroots(repo, targetphase, nodes - filtered, tr) self.invalidate() def filterunknown(self, repo: "localrepo.localrepository") -> None: