[PATCH 3 of 5] obsolete: detect divergent changesets

Pierre-Yves David pierre-yves.david at ens-lyon.org
Fri Nov 9 19:23:46 CST 2012


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at logilab.fr>
# Date 1352509811 -3600
# Node ID 135802bc01b47fc34154dd41a698b18fb882c83a
# Parent  929a4dc33ad3401ced4b099bdbf29d714115d2df
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.

diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py
--- a/mercurial/obsolete.py
+++ b/mercurial/obsolete.py
@@ -625,6 +625,28 @@
     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
 
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -641,6 +641,15 @@
 
     return [r for r in subset if r in dests]
 
+def divergent(repo, subset, x):
+    """``divergent()``
+    Final successors of changesets with an alternative set of final successors.
+    """
+    # i18n: "divergent" is a keyword
+    getargs(x, 0, 0, _("divergent takes no arguments"))
+    divergent = obsmod.getrevs(repo, 'divergent')
+    return [r for r in subset if r in divergent]
+
 def draft(repo, subset, x):
     """``draft()``
     Changeset in draft phase."""
@@ -1536,6 +1545,7 @@
     "descendants": descendants,
     "_firstdescendants": _firstdescendants,
     "destination": destination,
+    "divergent": divergent,
     "draft": draft,
     "extinct": extinct,
     "extra": extra,
diff --git a/tests/test-obsolete-divergent.t b/tests/test-obsolete-divergent.t
--- a/tests/test-obsolete-divergent.t
+++ b/tests/test-obsolete-divergent.t
@@ -81,6 +81,9 @@
       82623d38b9ba
   392fd25390da
       392fd25390da
+  $ hg log -r 'divergent()'
+  2:82623d38b9ba A_1
+  3:392fd25390da A_2
   $ cd ..
 
 
@@ -116,6 +119,9 @@
       01f36c5a8fda
   01f36c5a8fda
       01f36c5a8fda
+  $ hg log -r 'divergent()'
+  2:82623d38b9ba A_1
+  4:01f36c5a8fda A_3
   $ cd ..
 
 
@@ -145,6 +151,9 @@
       82623d38b9ba
   392fd25390da
       392fd25390da
+  $ hg log -r 'divergent()'
+  2:82623d38b9ba A_1
+  3:392fd25390da A_2
   $ cd ..
 
 do not take unknown node in account if they are final
@@ -195,6 +204,7 @@
       01f36c5a8fda
   01f36c5a8fda
       01f36c5a8fda
+  $ hg log -r 'divergent()'
   $ cd ..
 
 split is not divergences
@@ -220,6 +230,7 @@
       82623d38b9ba
   392fd25390da
       392fd25390da
+  $ hg log -r 'divergent()'
 
 Even when subsequente rewriting happen
 
@@ -266,6 +277,7 @@
       e442cfc57690
   e442cfc57690
       e442cfc57690
+  $ hg log -r 'divergent()'
 
 Check more complexe obsolescence graft (with divergence)
 
@@ -334,6 +346,11 @@
       14608b260df8
   bed64f5d2f5a
       bed64f5d2f5a
+  $ hg log -r 'divergent()'
+  4:01f36c5a8fda A_3
+  8:7ae126973a96 A_7
+  9:14608b260df8 A_8
+  10:bed64f5d2f5a A_9
 
 fix the divergence
 
@@ -393,6 +410,7 @@
       a139f71be9da
   a139f71be9da
       a139f71be9da
+  $ hg log -r 'divergent()'
 
   $ cd ..
 


More information about the Mercurial-devel mailing list