dagop: add smartset interface to filectxancestors()

The original filectx API is kept public since we'll need it to walk ancestor
(rev, match) pairs efficiently. The current implementation scans ancestors
twice for 'hg log -fp FILE'.
This commit is contained in:
Yuya Nishihara 2017-10-22 18:57:42 +09:00
parent e206413cfc
commit e49a4312a9
2 changed files with 20 additions and 10 deletions

View File

@ -77,7 +77,10 @@ def _walkrevtree(pfunc, revs, startdepth, stopdepth, reverse):
def filectxancestors(fctxs, followfirst=False):
"""Like filectx.ancestors(), but can walk from multiple files/revisions,
and includes the given fctxs themselves"""
and includes the given fctxs themselves
Yields (rev, {fctx, ...}) pairs in descending order.
"""
visit = {}
def addvisit(fctx):
rev = fctx.rev()
@ -93,13 +96,21 @@ def filectxancestors(fctxs, followfirst=False):
for c in fctxs:
addvisit(c)
while visit:
rev = max(visit)
c = visit[rev].pop()
if not visit[rev]:
del visit[rev]
yield c
for parent in c.parents()[:cut]:
addvisit(parent)
currev = max(visit)
curfctxs = visit.pop(currev)
yield currev, curfctxs
for c in curfctxs:
for parent in c.parents()[:cut]:
addvisit(parent)
def filerevancestors(fctxs, followfirst=False):
"""Like filectx.ancestors(), but can walk from multiple files/revisions,
and includes the given fctxs themselves
Returns a smartset.
"""
gen = (rev for rev, _cs in filectxancestors(fctxs, followfirst))
return generatorset(gen, iterasc=False)
def _genrevancestors(repo, revs, followfirst, startdepth, stopdepth, cutfunc):
if followfirst:

View File

@ -928,8 +928,7 @@ def _follow(repo, subset, x, name, followfirst=False):
files = c.manifest().walk(matcher)
fctxs = [c[f].introfilectx() for f in files]
a = dagop.filectxancestors(fctxs, followfirst)
s = set(c.rev() for c in a)
s = dagop.filerevancestors(fctxs, followfirst)
else:
s = dagop.revancestors(repo, baseset([c.rev()]), followfirst)