--- a/states.py Mon May 23 16:40:58 2011 +0200
+++ b/states.py Mon May 23 17:15:47 2011 +0200
@@ -26,15 +26,16 @@
from mercurial import templatekw
from mercurial import util
from mercurial import node
-from mercurial.node import nullid
+from mercurial.node import nullid, hex, short
from mercurial import discovery
from mercurial import extensions
from mercurial import wireproto
_NOPULLPUSH=2
+_MUTABLE=1
-STATES = (0, _NOPULLPUSH)
+STATES = (0, _MUTABLE, _NOPULLPUSH | _MUTABLE)
def statename(state):
return str(STATES)
@@ -61,16 +62,20 @@
# New revset predicate
#############################
-def revsetpublicheads(repo, subset, x):
- args = revset.getargs(x, 0, 0, 'publicheads takes no arguments')
- heads = map(repo.changelog.rev, repo._statesheads[0])
- heads.sort()
- return heads
+def revsetstatehead(state):
+ def revsetpublicheads(repo, subset, x):
+ args = revset.getargs(x, 0, 0, 'publicheads takes no arguments')
+ heads = map(repo.changelog.rev, repo._statesheads[state])
+ heads.sort()
+ return heads
+ return revsetpublicheads
def extsetup(ui):
- revset.symbols['publicheads'] = revsetpublicheads
+ revset.symbols['frozenheads'] = revsetstatehead(0)
+ revset.symbols['publicheads'] = revsetstatehead(1)
-REVSETHEADS = {0: 'publicheads()'}
+REVSETHEADS = {0: 'frozenheads()',
+ 1: 'publicheads()'}
# New commands
#############################
@@ -133,13 +138,23 @@
for head in self._publicheads:
revhead = self.changelog.rev(head)
if self.changelog.descendant(revhead, rev):
+ return STATES[2]
+ for head in self._frozenheads:
+ revhead = self.changelog.rev(head)
+ if self.changelog.descendant(revhead, rev):
return STATES[1]
return STATES[0]
@property
def _publicheads(self):
if self.ui.configbool('states', 'private', False):
- return self._statesheads[0]
+ return self._statesheads[1]
+ return self.heads()
+
+ @property
+ def _frozenheads(self):
+ if self.ui.configbool('states', 'liquid', False):
+ return self._statesheads[O]
return self.heads()
@util.propertycache
@@ -147,28 +162,36 @@
return self._readstatesheads()
- def _readstatesheads(self):
- statesheads = {}
+ def _readheadsfile(self, filename):
+ heads = [nullid]
try:
- f = self.opener('publicheads')
+ f = self.opener(filename)
try:
heads = sorted([node.bin(n) for n in f.read().split() if n])
finally:
f.close()
except IOError:
- heads = [nullid]
- statesheads[0] = heads
+ pass
+ return heads
+ def _readstatesheads(self):
+ statesheads = {}
+ statesheads[0] = self._readheadsfile('frozenheads')
+ statesheads[1] = self._readheadsfile('publicheads')
return statesheads
+ def _writeheadsfile(self, filename, heads):
+ f = self.opener(filename, 'w', atomictemp=True)
+ try:
+ for h in heads:
+ f.write(hex(h) + '\n')
+ f.rename()
+ finally:
+ f.close()
+
def _writestateshead(self):
# transaction!
- f = self.opener('publicheads', 'w', atomictemp=True)
- try:
- for h in self._statesheads[0]:
- f.write(node.hex(h) + '\n')
- f.rename()
- finally:
- f.close()
+ self._writeheadsfile('frozenheads', self._statesheads[0])
+ self._writeheadsfile('publicheads', self._statesheads[1])
def setstate(self, state, nodes):
"""freeze targets changeset and it's ancestors.
@@ -184,6 +207,8 @@
heads.sort()
if olds != heads:
self._writestateshead()
+ if state < 1:
+ self.setstate(1, nodes) # cascading
def _reducehead(self, candidates):
selected = set()
--- a/tests/test-private.t Mon May 23 16:40:58 2011 +0200
+++ b/tests/test-private.t Mon May 23 17:15:47 2011 +0200
@@ -48,8 +48,8 @@
> private=yes
> EOF
$ hg log --template='{rev}:{node|short}: {state}\n'
- 3:73585b17392a: 2
- 2:3c8695235a32: 2
+ 3:73585b17392a: 3
+ 2:3c8695235a32: 3
1:710fe444b3b0: 0
0:5caa672bac26: 0