obsolete.py
changeset 32 c27491be4431
child 37 9493ffa68633
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/obsolete.py	Fri Jul 29 18:54:05 2011 +0200
@@ -0,0 +1,104 @@
+# obsolete.py - introduce the obsolete concept in mercurial.
+#
+# Copyright 2011 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
+#                Logilab SA        <contact@logilab.fr>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from mercurial import util
+from mercurial import context
+from mercurial.node import hex, bin
+
+# Patch changectx
+#############################
+
+def obsolete(ctx):
+    if ctx.node()is None:
+        return False
+    return boolean(ctx._repo.obsoleteby(ctx.node()))
+
+context.changectx.obsolete = obsolete
+
+ohidden = context.changectx.hidden
+def hidden(ctx):
+    ctx._repo._obsobjrels # XXX hack to fill hiddenrevs
+    return ohidden(ctx)
+context.changectx.hidden = hidden
+
+# New commands
+#############################
+
+
+def cmddebugobsolete(ui, repo, subject, object):
+    """show enabled states"""
+    sub = repo[subject]
+    obj = repo[object]
+    repo.addobsolete(sub.node(), obj.node())
+    return 0
+
+cmdtable = {'debugobsolete': (cmddebugobsolete, [], '<subject> <object>')}
+
+def reposetup(ui, repo):
+
+    class obsoletingrepo(repo.__class__):
+
+        @util.propertycache
+        def hiddenrevs(self):
+            revs = set()
+            return revs
+
+        @util.propertycache
+        def _obsobjrels(self):
+            objrels = {}
+            for sub, objs in self._obssubrels.iteritems():
+                for obj in objs:
+                    objrels.setdefault(obj, set()).add(sub)
+            for obj in objrels:
+                self.changelog.hiddenrevs.add(repo[obj].rev())
+            return objrels
+
+        @util.propertycache
+        def _obssubrels(self):
+            return self._readobsrels()
+
+
+        def _readobsrels(self):
+            rels = {}
+            try:
+                f = self.opener('obsolete-relations')
+                try:
+                    for line in f:
+                        subhex, objhex = line.split()
+                        rels.setdefault(bin(subhex), set()).add(bin(objhex))
+                finally:
+                    f.close()
+            except IOError:
+                pass
+            return rels
+
+        def _writeobsrels(self):
+            f = self.opener('obsolete-relations', 'w', atomictemp=True)
+            try:
+                for sub, objs in self._obssubrels.iteritems():
+                    for obj in objs:
+                        f.write('%s %s\n' % (hex(sub), hex(obj)))
+                f.rename()
+            finally:
+                f.close()
+
+        def obsoletedby(self, node):
+            return self._readobsrels.get(node, set())
+
+        def obsolete(self, node):
+            return self._readsubrels.get(node, set())
+
+        def addobsolete(self, sub, obj):
+            self._obssubrels.setdefault(sub, set()).add(obj)
+            self._obsobjrels.setdefault(obj, set()).add(sub)
+            self.changelog.hiddenrevs.add(repo[obj].rev())
+            self._writeobsrels()
+
+    repo.__class__ = obsoletingrepo
+
+