src/topic/__init__.py
changeset 1839 1bc5e62fc0c7
child 1841 72a58a5bfb62
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/topic/__init__.py	Wed May 20 21:23:28 2015 -0400
@@ -0,0 +1,93 @@
+# __init__.py - topic extension
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+"""Adds topic branches. Topic branches are lightweight branches which
+dissappear when changes are finalized.
+
+This is sort of similar to a bookmark, but it applies to a whole
+series instead of a single revision.
+"""
+import functools
+
+from mercurial import cmdutil
+from mercurial import commands
+from mercurial import extensions
+from mercurial import namespaces
+from mercurial import phases
+from mercurial import util
+
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+
+def _namemap(repo, name):
+    return [ctx.node() for ctx in
+            repo.set('not public() and extra(topic, %s)', name)]
+
+def _nodemap(repo, node):
+    ctx = repo[node]
+    t = ctx.extra().get('topic', '')
+    if t and ctx.phase() > phases.public:
+        return [t]
+    return []
+
+def reposetup(ui, repo):
+    orig = repo.__class__
+    class topicrepo(repo.__class__):
+        def commitctx(self, ctx, error=None):
+            current = self.currenttopic
+            if current:
+                ctx.extra()['topic'] = current
+            return orig.commitctx(self, ctx, error=error)
+
+        @property
+        def topics(self):
+            topics = set(['', self.currenttopic])
+            for rev in self.revs('not public()'):
+                c = self.changectx(rev)
+                topics.add(c.extra().get('topic', ''))
+            topics.remove('')
+            return topics
+
+        @property
+        def currenttopic(self):
+            return self.vfs.tryread('topic')
+
+    if util.safehasattr(repo, 'names'):
+        repo.names.addnamespace(namespaces.namespace(
+            'topics', 'topic', namemap=_namemap, nodemap=_nodemap))
+    repo.__class__ = topicrepo
+
+@command('topics', [
+    ('', 'clear', False, 'clear active topic if any'),
+])
+def topics(ui, repo, topic=None, clear=False):
+    """View current topic, set current topic, or see all topics."""
+    if clear:
+        if repo.vfs.exists('topic'):
+            repo.vfs.unlink('topic')
+        return
+    if topic is not None:
+        with repo.vfs.open('topic', 'w') as f:
+            f.write(topic)
+        return
+    current = repo.currenttopic
+    for t in sorted(repo.topics):
+        marker = '*' if t == current else ' '
+        ui.write(' %s %s\n' % (marker, t))
+
+
+def updatewrap(orig, ui, repo, *args, **kwargs):
+    ret = orig(ui, repo, *args, **kwargs)
+    pctx = repo['.']
+    if pctx.phase() == phases.public and repo.vfs.exists('topic'):
+        repo.vfs.unlink('topic')
+    else:
+        # inherit the topic of the parent revision
+        t = pctx.extra().get('topic', '')
+        if t and pctx.phase() > phases.public:
+            with repo.vfs.open('topic', 'w') as f:
+                f.write(t)
+    return ret
+
+extensions.wrapcommand(commands.table, 'update', updatewrap)