[PATCH 3 of 6 V2] obsolete: detect divergent changesets
pierre-yves.david at logilab.fr
pierre-yves.david at logilab.fr
Thu Dec 13 08:51:50 CST 2012
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at logilab.fr>
# Date 1355278770 -3600
# Node ID cfc7306dbdc75659ca4c85a14720f8de87cd797e
# Parent a63af12dc0cdf8e7c828f2278427b3beea1220c2
obsolete: detect divergent changesets
Divergent changeset are final successors (non obsolete) of a changeset who
compete with another set of final successors for this same changeset.
For example if you have two obsolescence markers A -> B and A -> C, B and C are
both "divergent" because they compete to be the one true successors of A.
Public revision can't be divergent.
This function is used and tested in the next changeset.
diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py
--- a/mercurial/obsolete.py
+++ b/mercurial/obsolete.py
@@ -684,10 +684,32 @@ def _computebumpedset(repo):
ignoreflags=bumpedfix)
# revision public or already obsolete don't count as bumped
query = '%ld - obsolete() - public()'
return set(repo.revs(query, _knownrevs(repo, successors)))
+ at cachefor('divergent')
+def _computedivergentset(repo):
+ """the set of rev that compete to be the final successors of some revision.
+ """
+ divergent = set()
+ obsstore = repo.obsstore
+ newermap = {}
+ for ctx in repo.set('(not public()) - obsolete()'):
+ mark = obsstore.precursors.get(ctx.node(), ())
+ toprocess = set(mark)
+ while toprocess:
+ prec = toprocess.pop()[0]
+ if prec not in newermap:
+ successorssets(repo, prec, newermap)
+ newer = [n for n in newermap[prec] if n]
+ if len(newer) > 1:
+ divergent.add(ctx.rev())
+ break
+ toprocess.update(obsstore.precursors.get(prec, ()))
+ return divergent
+
+
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