# HG changeset patch # User Pierre-Yves David # Date 1355278770 -3600 # Node ID af632936d3d97fa052cf50f9cb73b798e38f74e6 # Parent f84e731cbd204a08347798641d802215562bad87 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 -r f84e731cbd20 -r af632936d3d9 mercurial/obsolete.py --- a/mercurial/obsolete.py Sat Nov 10 01:56:59 2012 +0100 +++ b/mercurial/obsolete.py Wed Dec 12 03:19:30 2012 +0100 @@ -684,6 +684,28 @@ query = '%ld - obsolete() - public()' return set(repo.revs(query, _knownrevs(repo, successors))) +@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