[PATCH 2 of 7] obsolete: add the detection of bumped changeset
pierre-yves.david at logilab.fr
pierre-yves.david at logilab.fr
Wed Oct 3 05:13:02 CDT 2012
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at logilab.fr>
# Date 1349257695 -7200
# Node ID 7866831b6cb69e817c1fe0fec81bb933fd46ae45
# 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
@@ -69,10 +69,13 @@ from i18n import _
_fmfixed = '>BIB20s'
_fmnode = '20s'
_fmfsize = struct.calcsize(_fmfixed)
_fnodesize = struct.calcsize(_fmnode)
+# obsolescence marker flag
+bumpedfix = 1
+
def _readmarkers(data):
"""Read and enumerate markers from raw data"""
off = 0
diskversion = _unpack('>B', data[off:off + 1])[0]
off += 1
@@ -397,10 +400,52 @@ def _computesuspendedset(repo):
@cachefor('extinct')
def _computeextinctset(repo):
"""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
<relations> must be an iterable of (<old>, (<new>, ...)) tuple.
`old` and `news` are changectx.
More information about the Mercurial-devel
mailing list