view obsolete.py @ 32:c27491be4431

obsolet: basic support (hide changeset)
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Fri, 29 Jul 2011 18:54:05 +0200
parents
children 9493ffa68633
line wrap: on
line source

# 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