more doc and cleanup
authorPierre-Yves David <pierre-yves.david@logilab.fr>
Wed, 08 Aug 2012 12:59:32 +0200
changeset 451 dc1bd3595075
parent 450 4d18739b506b
child 452 3cf7ce72dbda
more doc and cleanup
hgext/obsolete.py
--- a/hgext/obsolete.py	Wed Aug 08 11:54:27 2012 +0200
+++ b/hgext/obsolete.py	Wed Aug 08 12:59:32 2012 +0200
@@ -476,6 +476,18 @@
 ### Complete troubles computation logic                           ###
 #####################################################################
 
+# there is two kind of trouble not handled by core right now:
+# - latecomer: (successors for public changeset)
+# - conflicting: (two changeset try to succeed to the same precursors)
+#
+# This section add support for those two addition trouble
+#
+# - Cache computation
+# - revset and ctx method
+# - push warning
+
+### Cache computation
+
 @cachefor('latecomer')
 def _computelatecomerset(repo):
     """the set of rev trying to obsolete public revision"""
@@ -502,6 +514,8 @@
         toprocess.update(obsstore.successors.get(prec, ()))
     return conflicting
 
+### changectx method
+
 @eh.addattr(context.changectx, 'latecomer')
 def latecomer(ctx):
     """is the changeset latecomer (Try to succeed to public change)"""
@@ -516,14 +530,34 @@
         return False
     return ctx.rev() in getobscache(ctx._repo, 'conflicting')
 
+### revset symbol
+
+@eh.revset('latecomer')
+def revsetlatecomer(repo, subset, x):
+    """``latecomer()``
+    Changesets marked as successors of public changesets.
+    """
+    args = revset.getargs(x, 0, 0, 'latecomer takes no arguments')
+    lates = getobscache(repo, 'latecomer')
+    return [r for r in subset if r in lates]
+
+@eh.revset('conflicting')
+def revsetconflicting(repo, subset, x):
+    """``conflicting()``
+    Changesets marked as successors of a same changeset.
+    """
+    args = revset.getargs(x, 0, 0, 'conflicting takes no arguments')
+    conf = getobscache(repo, 'conflicting')
+    return [r for r in subset if r in conf]
+
+
 ### Discovery wrapping
 
 @eh.wrapfunction(discovery, 'checkheads')
 def wrapcheckheads(orig, repo, remote, outgoing, *args, **kwargs):
     """wrap mercurial.discovery.checkheads
 
-    * prevent unstability to be pushed
-    * patch remote to ignore obsolete heads on remote
+    * prevent latecomer and unstable to be pushed
     """
     # do not push instability
     for h in outgoing.missingheads:
@@ -543,6 +577,53 @@
 ### Additional Utilities                                          ###
 #####################################################################
 
+# This section contains a lot of small utility function and method
+
+# - Function to create markers
+# - useful alias pstatus and pdiff (should probably go in evolve)
+# - "troubles" method on changectx
+# - function to travel throught the obsolescence graph
+# - function to find useful changeset to stabilize
+
+### Marker Create
+
+def createmarkers(repo, relations, metadata=None, flag=0):
+    """Add obsolete markers between changeset in a repo
+
+    <relations> must be an iterable of (<old>, (<new>, ...)) tuple.
+    `old` and `news` are changectx.
+
+    Current user and date are used except if specified otherwise in the
+    metadata attribute.
+
+    /!\ assume the repo have been locked byt the user /!\
+    """
+    # prepare metadata
+    if metadata is None:
+        metadata = {}
+    if 'date' not in metadata:
+        metadata['date'] = '%i %i' % util.makedate()
+    if 'user' not in metadata:
+        metadata['user'] = repo.ui.username()
+    # check future marker
+    tr = repo.transaction('add-obsolescence-marker')
+    try:
+        for prec, sucs in relations:
+            if not prec.mutable():
+                raise util.Abort("Cannot obsolete immutable changeset: %s" % prec)
+            nprec = prec.node()
+            nsucs = tuple(s.node() for s in sucs)
+            if nprec in nsucs:
+                raise util.Abort("Changeset %s cannot obsolete himself" % prec)
+            repo.obsstore.create(tr, nprec, nsucs, flag, metadata)
+            clearobscaches(repo)
+        tr.close()
+    finally:
+        tr.release()
+
+
+### Useful alias
+
 @eh.uisetup
 def _installalias(ui):
     if ui.config('alias', 'pstatus', None) is None:
@@ -550,6 +631,26 @@
     if ui.config('alias', 'pdiff', None) is None:
         ui.setconfig('alias', 'pdiff', 'diff --rev .^')
 
+# - "troubles" method on changectx
+
+@eh.addattr(context.changectx, 'troubles')
+def troubles(ctx):
+    """Return a tuple listing all the troubles that affect a changeset
+
+    Troubles may be "unstable", "latecomer" or "conflicting".
+    """
+    troubles = []
+    if ctx.unstable():
+        troubles.append('unstable')
+    if ctx.latecomer():
+        troubles.append('latecomer')
+    if ctx.conflicting():
+        troubles.append('conflicting')
+    return tuple(troubles)
+
+
+### Obsolescence graph
+
 def _precursors(repo, s):
     """Precursor of a changeset"""
     cs = set()
@@ -616,11 +717,6 @@
     return cs
 
 
-### diagnostique tools
-
-def unstables(repo):
-    """Return all unstable changeset"""
-    return scmutil.revrange(repo, ['obsolete():: and (not obsolete())'])
 
 def newerversion(repo, obs):
     """Return the newer version of an obsolete changeset"""
@@ -644,39 +740,11 @@
             newer.add(())
     return sorted(newer)
 
-def createmarkers(repo, relations, metadata=None, flag=0):
-    """Add obsolete markers between changeset in a repo
-
-    <relations> must be an iterable of (<old>, (<new>, ...)) tuple.
-    `old` and `news` are changectx.
-
-    Current user and date are used except if specified otherwise in the
-    metadata attribute.
+### diagnostique tools
 
-    /!\ assume the repo have been locked byt the user /!\
-    """
-    # prepare metadata
-    if metadata is None:
-        metadata = {}
-    if 'date' not in metadata:
-        metadata['date'] = '%i %i' % util.makedate()
-    if 'user' not in metadata:
-        metadata['user'] = repo.ui.username()
-    # check future marker
-    tr = repo.transaction('add-obsolescence-marker')
-    try:
-        for prec, sucs in relations:
-            if not prec.mutable():
-                raise util.Abort("Cannot obsolete immutable changeset: %s" % prec)
-            nprec = prec.node()
-            nsucs = tuple(s.node() for s in sucs)
-            if nprec in nsucs:
-                raise util.Abort("Changeset %s cannot obsolete himself" % prec)
-            repo.obsstore.create(tr, nprec, nsucs, flag, metadata)
-            clearobscaches(repo)
-        tr.close()
-    finally:
-        tr.release()
+def unstables(repo):
+    """Return all unstable changeset"""
+    return scmutil.revrange(repo, ['obsolete():: and (not obsolete())'])
 
 #####################################################################
 ### Extending revset and template                                 ###
@@ -701,24 +769,6 @@
     suspended = getobscache(repo, 'suspended')
     return [r for r in subset if r in suspended]
 
-@eh.revset('latecomer')
-def revsetlatecomer(repo, subset, x):
-    """``latecomer()``
-    Changesets marked as successors of public changesets.
-    """
-    args = revset.getargs(x, 0, 0, 'latecomer takes no arguments')
-    lates = getobscache(repo, 'latecomer')
-    return [r for r in subset if r in lates]
-
-@eh.revset('conflicting')
-def revsetconflicting(repo, subset, x):
-    """``conflicting()``
-    Changesets marked as successors of a same changeset.
-    """
-    args = revset.getargs(x, 0, 0, 'conflicting takes no arguments')
-    conf = getobscache(repo, 'conflicting')
-    return [r for r in subset if r in conf]
-
 
 @eh.revset('precursors')
 def revsetprecursors(repo, subset, x):