mercurial/revset.py
changeset 33377 5d63e5f40bea
parent 33336 4672db164c98
child 33416 9467d5337292
--- a/mercurial/revset.py	Mon Jul 10 21:55:43 2017 -0700
+++ b/mercurial/revset.py	Mon Jul 10 10:56:40 2017 -0700
@@ -19,6 +19,7 @@
     match as matchmod,
     node,
     obsolete as obsmod,
+    obsutil,
     pathutil,
     phases,
     registrar,
@@ -1826,6 +1827,28 @@
 
     return subset.filter(matches, condrepr=('<subrepo %r>', pat))
 
+def _mapbynodefunc(repo, s, f):
+    """(repo, smartset, [node] -> [node]) -> smartset
+
+    Helper method to map a smartset to another smartset given a function only
+    talking about nodes. Handles converting between rev numbers and nodes, and
+    filtering.
+    """
+    cl = repo.unfiltered().changelog
+    torev = cl.rev
+    tonode = cl.node
+    nodemap = cl.nodemap
+    result = set(torev(n) for n in f(tonode(r) for r in s) if n in nodemap)
+    return smartset.baseset(result - repo.changelog.filteredrevs)
+
+@predicate('successors(set)', safe=True)
+def successors(repo, subset, x):
+    """All successors for set, including the given set themselves"""
+    s = getset(repo, fullreposet(repo), x)
+    f = lambda nodes: obsutil.allsuccessors(repo.obsstore, nodes)
+    d = _mapbynodefunc(repo, s, f)
+    return subset & d
+
 def _substringmatcher(pattern, casesensitive=True):
     kind, pattern, matcher = util.stringmatcher(pattern,
                                                 casesensitive=casesensitive)