# 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