phases: add a getrevset method to phasecache
This is part of a refactoring that moves some phase query optimization from
revset.py to phases.py.
The motivation behind this was chg repo preloading - to make the obsstore
depend on less things (like the revset language). The refactoring also looks
good by itself - phasecache does not expose its private field "_phasesets"
via public methods and revset.py is accessing it in a hacky way.
This patch adds a "getrevset" method, which takes multiple phases and
returns a revset in an best-effort efficient way - for "public" phase, it
returns a lazy generatorset; for "draft" and "secret", it returns efficient
"baseset".
--- a/mercurial/phases.py Fri Feb 17 20:59:29 2017 -0800
+++ b/mercurial/phases.py Fri Feb 17 22:49:05 2017 -0800
@@ -115,6 +115,7 @@
from . import (
encoding,
error,
+ smartset,
)
allphases = public, draft, secret = range(3)
@@ -170,6 +171,27 @@
self.filterunknown(repo)
self.opener = repo.svfs
+ def getrevset(self, repo, phases):
+ """return a smartset for the given phases"""
+ self.loadphaserevs(repo) # ensure phase's sets are loaded
+
+ if self._phasesets and all(self._phasesets[p] is not None
+ for p in phases):
+ # fast path - use _phasesets
+ revs = self._phasesets[phases[0]]
+ if len(phases) > 1:
+ revs = revs.copy() # only copy when needed
+ for p in phases[1:]:
+ revs.update(self._phasesets[p])
+ if repo.changelog.filteredrevs:
+ revs = revs - repo.changelog.filteredrevs
+ return smartset.baseset(revs)
+ else:
+ # slow path - enumerate all revisions
+ phase = self.phase
+ revs = (r for r in repo if phase(repo, r) in phases)
+ return smartset.generatorset(revs, iterasc=True)
+
def copy(self):
# Shallow copy meant to ensure isolation in
# advance/retractboundary(), nothing more.