Mercurial > evolve
view obsolete.py @ 41:99c131e97bb3
Do not hide current and bookmarked
author | Pierre-Yves David <pierre-yves.david@logilab.fr> |
---|---|
date | Wed, 07 Sep 2011 18:39:02 +0200 |
parents | b9a5a596d9ef |
children | eb6a06d7eae3 |
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 import revset from mercurial import scmutil from mercurial.node import hex, bin # Patch changectx ############################# def obsolete(ctx): """is the changeset obsolete by other""" if ctx.node()is None: return False return bool(ctx._repo.obsoletedby(ctx.node())) context.changectx.obsolete = obsolete ohidden = context.changectx.hidden def hidden(ctx): # hack to fill hiddenrevs # compute hidden (XXX should move elsewhere) if not getattr(ctx._repo.changelog, 'hiddeninit', False): basicquery = 'obsolete() - (ancestors(not obsolete() or . or bookmark()))' for rev in scmutil.revrange(ctx._repo, [basicquery]): ctx._repo.changelog.hiddenrevs.add(rev) ctx._repo.changelog.hiddeninit = True return ohidden(ctx) context.changectx.hidden = hidden # revset ############################# def revsetobsolete(repo, subset, x): args = revset.getargs(x, 0, 0, 'publicheads takes no arguments') return [r for r in subset if repo[r].obsolete()] # XXX slow def extsetup(ui): revset.symbols["obsolete"] = revsetobsolete # New commands ############################# def cmddebugobsolete(ui, repo, subject, object): """Add an obsolete relation between a too node The subject is expected to be a newer version of the object""" 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): # It's a property because It simpler that to handle the __init__ revs = set() return revs @util.propertycache def _obsobjrels(self): """{<old-node> -> set(<new-node>)} also compute hidden revision""" #reverse sub -> objs mapping objrels = {} for sub, objs in self._obssubrels.iteritems(): for obj in objs: objrels.setdefault(obj, set()).add(sub) # return objrels @util.propertycache def _obssubrels(self): """{<new-node> -> set(<old-node>)}""" return self._readobsrels() ### Disk IO def _readobsrels(self): """Write obsolete relation on disk""" # XXX handle lock 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): """Write obsolete relation on disk""" # XXX handle lock 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() ### Public method def obsoletedby(self, node): """return the set of node that make <node> obsolete (obj)""" return self._obsobjrels.get(node, set()) def obsolete(self, node): """return the set of node that <node> make obsolete (sub)""" return self._obssubrels.get(node, set()) def addobsolete(self, sub, obj): """Add a relation marking that node <sub> is a new version of <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