--- a/states.py Mon May 23 17:15:47 2011 +0200
+++ b/states.py Wed May 25 01:46:48 2011 +0200
@@ -32,13 +32,52 @@
from mercurial import wireproto
-_NOPULLPUSH=2
+_NOSHARE=2
_MUTABLE=1
-STATES = (0, _MUTABLE, _NOPULLPUSH | _MUTABLE)
-def statename(state):
- return str(STATES)
+class state(object):
+
+ def __init__(self, name, order=0, next=None):
+ self.name = name
+ self.order = order
+ assert next is None or self < next
+ self.next = next
+
+ def __repr__(self):
+ return 'state(%s)' % self.name
+
+ def __str__(self):
+ return self.name
+
+ @util.propertycache
+ def trackheads(self):
+ return self.next is not None
+
+ def __cmp__(self, other):
+ return cmp(self.order, other.order)
+ @util.propertycache
+ def _revsetheads(self):
+ assert self.trackheads
+ def revsetheads(repo, subset, x):
+ args = revset.getargs(x, 0, 0, 'publicheads takes no arguments')
+ heads = map(repo.changelog.rev, repo._statesheads[self])
+ heads.sort()
+ return heads
+ return revsetheads
+
+ @util.propertycache
+ def headssymbol(self):
+ if self.trackheads:
+ return "%sheads" % self.name
+ else:
+ return 'heads'
+
+STDRAFT = state('draft', _NOSHARE | _MUTABLE)
+STREADY = state('ready', _MUTABLE, next=STDRAFT)
+STPUBLISHED = state('published', next=STREADY)
+
+STATES = (STPUBLISHED, STREADY, STDRAFT)
# util function
#############################
@@ -62,34 +101,29 @@
# New revset predicate
#############################
-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['frozenheads'] = revsetstatehead(0)
- revset.symbols['publicheads'] = revsetstatehead(1)
-
-REVSETHEADS = {0: 'frozenheads()',
- 1: 'publicheads()'}
+ for state in STATES:
+ if state.trackheads:
+ revset.symbols[state.headssymbol] = state._revsetheads
# New commands
#############################
-def cmdsetstate(ui, repo, state, *changesets):
+def cmdsetstate(ui, repo, statename, *changesets):
"""turn private changesets into public ones"""
#assert repo.ui.configbool('private', 'enable', False)
- state = int(state) #for now
+ for state in STATES: # few states
+ if state.name == statename:
+ break
+ else:
+ raise util.Abort(_('unknown state: %s') % statename)
revs = scmutil.revrange(repo, changesets)
repo.setstate(state, [repo.changelog.node(rev) for rev in revs])
return 0
cmdtable = {
- 'setstate': (cmdsetstate, [], _('state <revset>')),
+ 'setstate': (cmdsetstate, [], _('<state> <revset>')),
}
@@ -148,13 +182,13 @@
@property
def _publicheads(self):
if self.ui.configbool('states', 'private', False):
- return self._statesheads[1]
+ return self._statesheads[STREADY]
return self.heads()
@property
def _frozenheads(self):
if self.ui.configbool('states', 'liquid', False):
- return self._statesheads[O]
+ return self._statesheads[STPUBLISHED]
return self.heads()
@util.propertycache
@@ -175,8 +209,8 @@
return heads
def _readstatesheads(self):
statesheads = {}
- statesheads[0] = self._readheadsfile('frozenheads')
- statesheads[1] = self._readheadsfile('publicheads')
+ statesheads[STPUBLISHED] = self._readheadsfile('frozenheads')
+ statesheads[STREADY] = self._readheadsfile('publicheads')
return statesheads
def _writeheadsfile(self, filename, heads):
@@ -190,8 +224,8 @@
def _writestateshead(self):
# transaction!
- self._writeheadsfile('frozenheads', self._statesheads[0])
- self._writeheadsfile('publicheads', self._statesheads[1])
+ self._writeheadsfile('frozenheads', self._statesheads[STPUBLISHED])
+ self._writeheadsfile('publicheads', self._statesheads[STREADY])
def setstate(self, state, nodes):
"""freeze targets changeset and it's ancestors.
@@ -203,12 +237,12 @@
heads[:] = set(heads)
heads.sort()
if olds != heads:
- heads[:] = noderange(repo, ["heads(::%s)" % REVSETHEADS[state]])
+ heads[:] = noderange(repo, ["heads(::%s())" % state.headssymbol])
heads.sort()
if olds != heads:
self._writestateshead()
- if state < 1:
- self.setstate(1, nodes) # cascading
+ if state.next is not None and state.next.trackheads:
+ self.setstate(state.next, nodes) # cascading
def _reducehead(self, candidates):
selected = set()
--- a/tests/test-private.t Mon May 23 17:15:47 2011 +0200
+++ b/tests/test-private.t Wed May 25 01:46:48 2011 +0200
@@ -16,8 +16,8 @@
$ echo "la veille dame" > babar
$ hg ci -m "add dame"
$ hg log --template='{rev}:{node|short}: {state}\n'
- 1:710fe444b3b0: 0
- 0:5caa672bac26: 0
+ 1:710fe444b3b0: published
+ 0:5caa672bac26: published
$ hg out ../remote1 --template='{rev}:{node|short}\n'
comparing with ../remote1
searching for changes
@@ -30,17 +30,17 @@
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files
- $ hg setstate 0 1 # until we fix push
+ $ hg setstate published 1 # until we fix push
$ echo "tree" >> savanna
$ hg add savanna
$ hg ci -m "terrain"
$ echo "flore" >> babar
$ hg ci -m "children"
$ hg log --template='{rev}:{node|short}: {state}\n'
- 3:73585b17392a: 0
- 2:3c8695235a32: 0
- 1:710fe444b3b0: 0
- 0:5caa672bac26: 0
+ 3:73585b17392a: published
+ 2:3c8695235a32: published
+ 1:710fe444b3b0: published
+ 0:5caa672bac26: published
turn private on (repo side)
$ cat > .hg/hgrc << EOF
@@ -48,10 +48,10 @@
> private=yes
> EOF
$ hg log --template='{rev}:{node|short}: {state}\n'
- 3:73585b17392a: 3
- 2:3c8695235a32: 3
- 1:710fe444b3b0: 0
- 0:5caa672bac26: 0
+ 3:73585b17392a: draft
+ 2:3c8695235a32: draft
+ 1:710fe444b3b0: published
+ 0:5caa672bac26: published
test outgoing and push
$ hg out ../remote1 --template='{rev}:{node|short}\n'
@@ -80,10 +80,10 @@
turn private off again (repo side)
$ sed -i 's/^private=.*$/private=no/' .hg/hgrc
$ hg log --template='{rev}:{node|short}: {state}\n'
- 3:73585b17392a: 0
- 2:3c8695235a32: 0
- 1:710fe444b3b0: 0
- 0:5caa672bac26: 0
+ 3:73585b17392a: published
+ 2:3c8695235a32: published
+ 1:710fe444b3b0: published
+ 0:5caa672bac26: published
$ hg out ../remote1 --template='{rev}:{node|short}\n'
comparing with ../remote1
searching for changes