src/topic/__init__.py
author Augie Fackler <augie@google.com>
Wed, 10 Jun 2015 14:59:46 -0400
changeset 1841 72a58a5bfb62
parent 1839 1bc5e62fc0c7
child 1842 94bbc18daa99
permissions -rw-r--r--
topic: use repo.set() where we need a changectx anyway I always forget repo.set() exists and use repo.revs(). Sigh.

# __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 c in self.set('not public()'):
                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)