[PATCH 2 of 7 V2] obsolete: add the detection of bumped changeset

Pierre-Yves David pierre-yves.david at ens-lyon.org
Wed Oct 3 16:21:55 CDT 2012


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at logilab.fr>
# Date 1349297225 -7200
# Node ID c09af8f861194656aa3465d2fd721749a61fdacb
# Parent  af731e6a342308e9111c11287bd73a1a0fcbbd47
obsolete: add the detection of bumped changeset.

Bumped changeset are non-public changeset that tries to succeed to a public()
changeset.

diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py
--- a/mercurial/obsolete.py
+++ b/mercurial/obsolete.py
@@ -399,6 +399,48 @@
     """the set of obsolete parents without non obsolete descendants"""
     return set(repo.revs('obsolete() - obsolete()::unstable()'))
 
+ at cachefor('bumped')
+def _computebumpedset(repo):
+    """the set of rev trying to obsolete public revision"""
+    # get all possible bumped changeset
+    candidates = _anysuccessors(repo, repo.revs('public()'))
+    # revision public or already obsolete don't account as bumped
+    query = '%ld - obsolete() - public()'
+    return set(repo.revs(query, candidates))
+
+def _anysuccessors(repo, revs):
+    """return revid of all successors of a set of revs
+    """
+    toproceed = [repo[r].node() for r in revs]
+    # prevent extra processing and cycle
+    seen = set(toproceed)
+    # records result
+    successors = set()
+    # mapping node -> marker that use node as precursors
+    markersfor = repo.obsstore.precursors
+    while toproceed:
+        nc = toproceed.pop()
+        # for all markers that make this node obsolete
+        for mark in markersfor.get(nc, ()):
+            # for all successors
+            for suc in mark[1]:
+                # record this as a successors
+                successors.add(suc)
+                # add it to the list of node to proceed
+                # we want the successors of this successors too.
+                if suc not in seen:
+                    seen.add(suc)
+                    toproceed.append(suc)
+    # only known nodes are returned
+    nm = repo.changelog.nodemap
+    cs = set()
+    for s in successors:
+        sr = nm.get(s)
+        if sr is not None:
+            cs.add(sr)
+    return cs
+
+
 def createmarkers(repo, relations, flag=0, metadata=None):
     """Add obsolete markers between changesets in a repo
 


More information about the Mercurial-devel mailing list