diff mercurial/obsutil.py @ 33146:7017567ebdf2

obsutil: move 'foreground' to the new modules We have a new 'obsutil' module now. We move the high level utility there to bring 'obsolete.py' back to a more reasonable size.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 27 Jun 2017 01:40:34 +0200
parents 0a370b93cca2
children 4e30168d7939
line wrap: on
line diff
--- a/mercurial/obsutil.py	Tue Jun 27 01:36:20 2017 +0200
+++ b/mercurial/obsutil.py	Tue Jun 27 01:40:34 2017 +0200
@@ -203,6 +203,32 @@
 
     return exclmarkers
 
+def foreground(repo, nodes):
+    """return all nodes in the "foreground" of other node
+
+    The foreground of a revision is anything reachable using parent -> children
+    or precursor -> successor relation. It is very similar to "descendant" but
+    augmented with obsolescence information.
+
+    Beware that possible obsolescence cycle may result if complex situation.
+    """
+    repo = repo.unfiltered()
+    foreground = set(repo.set('%ln::', nodes))
+    if repo.obsstore:
+        # We only need this complicated logic if there is obsolescence
+        # XXX will probably deserve an optimised revset.
+        nm = repo.changelog.nodemap
+        plen = -1
+        # compute the whole set of successors or descendants
+        while len(foreground) != plen:
+            plen = len(foreground)
+            succs = set(c.node() for c in foreground)
+            mutable = [c.node() for c in foreground if c.mutable()]
+            succs.update(allsuccessors(repo.obsstore, mutable))
+            known = (n for n in succs if n in nm)
+            foreground = set(repo.set('%ln::', known))
+    return set(c.node() for c in foreground)
+
 def successorssets(repo, initialnode, cache=None):
     """Return set of all latest successors of initial nodes