Patchwork D8694: phases: provide a test and accessor for non-public phase roots

login
register
mail settings
Submitter phabricator
Date July 7, 2020, 10:38 p.m.
Message ID <differential-rev-PHID-DREV-4gyxiaepr6f4qdyl5i26-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/46647/
State Superseded
Headers show

Comments

phabricator - July 7, 2020, 10:38 p.m.
joerg.sonnenberger created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  This decouples users from the implementation details of the phasecache.
  Also document a historic artifact about the stored phaseroots.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D8694

AFFECTED FILES
  mercurial/phases.py
  mercurial/repoview.py

CHANGE DETAILS




To: joerg.sonnenberger, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/mercurial/repoview.py b/mercurial/repoview.py
--- a/mercurial/repoview.py
+++ b/mercurial/repoview.py
@@ -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)))
diff --git a/mercurial/phases.py b/mercurial/phases.py
--- a/mercurial/phases.py
+++ b/mercurial/phases.py
@@ -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