# HG changeset patch # User Joerg Sonnenberger # Date 1594151110 -7200 # Node ID e2d17974a869a841de3c29036034b471b8091411 # Parent 98817e5daca7172a023331c4722a9bed7d4cd3b6 phases: provide a test and accessor for non-public phase roots This decouples users from the implementation details of the phasecache. Also document a historic artifact about the stored phaseroots. Differential Revision: https://phab.mercurial-scm.org/D8694 diff -r 98817e5daca7 -r e2d17974a869 mercurial/phases.py --- a/mercurial/phases.py Wed Jun 24 17:53:44 2020 +0200 +++ b/mercurial/phases.py Tue Jul 07 21:45:10 2020 +0200 @@ -323,6 +323,28 @@ self.filterunknown(repo) self.opener = repo.svfs + def hasnonpublicphases(self, repo): + """detect if there are revisions with non-public phase""" + repo = repo.unfiltered() + cl = repo.changelog + if len(cl) >= self._loadedrevslen: + self.invalidate() + self.loadphaserevs(repo) + return any(self.phaseroots[1:]) + + def nonpublicphaseroots(self, repo): + """returns the roots of all non-public phases + + The roots are not minimized, so if the secret revisions are + descendants of draft revisions, their roots will still be present. + """ + repo = repo.unfiltered() + cl = repo.changelog + if len(cl) >= self._loadedrevslen: + self.invalidate() + self.loadphaserevs(repo) + return set().union(*[roots for roots in self.phaseroots[1:] if roots]) + def getrevset(self, repo, phases, subset=None): """return a smartset for the given phases""" self.loadphaserevs(repo) # ensure phase's sets are loaded diff -r 98817e5daca7 -r e2d17974a869 mercurial/repoview.py --- a/mercurial/repoview.py Wed Jun 24 17:53:44 2020 +0200 +++ b/mercurial/repoview.py Tue Jul 07 21:45:10 2020 +0200 @@ -129,7 +129,7 @@ def computemutable(repo, visibilityexceptions=None): assert not repo.changelog.filteredrevs # fast check to avoid revset call on huge repo - if any(repo._phasecache.phaseroots[1:]): + if repo._phasecache.hasnonpublicphases(repo): getphase = repo._phasecache.phase maymutable = filterrevs(repo, b'base') return frozenset(r for r in maymutable if getphase(repo, r)) @@ -154,9 +154,9 @@ assert not repo.changelog.filteredrevs cl = repo.changelog firstmutable = len(cl) - for roots in repo._phasecache.phaseroots[1:]: - if roots: - firstmutable = min(firstmutable, min(cl.rev(r) for r in roots)) + roots = repo._phasecache.nonpublicphaseroots(repo) + if roots: + firstmutable = min(firstmutable, min(cl.rev(r) for r in roots)) # protect from nullrev root firstmutable = max(0, firstmutable) return frozenset(pycompat.xrange(firstmutable, len(cl)))