Add pull and push support for relevant heads.
This use pushkey.
--- a/states.py Mon Jun 06 16:52:03 2011 +0200
+++ b/states.py Mon Jun 06 16:42:56 2011 +0200
@@ -30,6 +30,7 @@
from mercurial import discovery
from mercurial import extensions
from mercurial import wireproto
+from mercurial import pushkey
_NOSHARE=2
@@ -88,6 +89,7 @@
STATES = (ST0, ST1, ST2)
+@util.cachefunc
def laststatewithout(prop):
for state in STATES:
if not state.properties & prop:
@@ -131,7 +133,22 @@
cmdmoveheads = makecmd(state)
cmdtable[state.name] = (cmdmoveheads, [], '<revset>')
+# Pushkey mechanism for mutable
+#########################################
+def pushimmutableheads(repo, key, old, new):
+ st = ST0
+ w = repo.wlock()
+ try:
+ #print 'pushing', key
+ repo.setstate(ST0, [node.bin(key)])
+ finally:
+ w.release()
+
+def listimmutableheads(repo):
+ return dict.fromkeys(map(node.hex, repo.stateheads(ST0)), '1')
+
+pushkey.register('immutableheads', pushimmutableheads, listimmutableheads)
@@ -175,7 +192,9 @@
if not repo.local():
return
- o_cancopy =repo.cancopy
+ ocancopy =repo.cancopy
+ opull =repo.pull
+ opush =repo.push
class statefulrepo(repo.__class__):
def nodestate(self, node):
@@ -241,9 +260,10 @@
self._writeheadsfile(filename, self._statesheads[state])
def setstate(self, state, nodes):
- """freeze targets changeset and it's ancestors.
+ """change state of targets changeset and it's ancestors.
Simplify the list of head."""
+ assert not isinstance(nodes, basestring)
heads = self._statesheads[state]
olds = heads[:]
heads.extend(nodes)
@@ -274,7 +294,43 @@
def cancopy(self):
st = laststatewithout(_NOSHARE)
- return o_cancopy() and (self.stateheads(st) == self.heads())
+ return ocancopy() and (self.stateheads(st) == self.heads())
+
+ def pull(self, remote, *args, **kwargs):
+ result = opull(remote, *args, **kwargs)
+ remoteheads = self._pullimmutableheads(remote)
+ #print [node.short(h) for h in remoteheads]
+ self.setstate(ST0, remoteheads)
+ return result
+
+ def push(self, remote, *args, **opts):
+ result = opush(remote, *args, **opts)
+ remoteheads = self._pullimmutableheads(remote)
+ self.setstate(ST0, remoteheads)
+ if remoteheads != self.stateheads(ST0):
+ #print 'stuff to push'
+ #print 'remote', [node.short(h) for h in remoteheads]
+ #print 'local', [node.short(h) for h in self._statesheads[ST0]]
+ self._pushimmutableheads(remote, remoteheads)
+ return result
+
+ def _pushimmutableheads(self, remote, remoteheads):
+ missing = set(self.stateheads(ST0)) - set(remoteheads)
+ for h in missing:
+ #print 'missing', node.short(h)
+ remote.pushkey('immutableheads', node.hex(h), '', '1')
+
+
+ def _pullimmutableheads(self, remote):
+ self.ui.debug('checking for immutableheadshg on server')
+ if 'immutableheads' not in remote.listkeys('namespaces'):
+ self.ui.debug('immutableheads not enabled on the remote server, '
+ 'marking everything as frozen')
+ remote = remote.heads()
+ else:
+ self.ui.debug('server has immutableheads enabled, merging lists')
+ remote = map(node.bin, remote.listkeys('immutableheads'))
+ return remote
repo.__class__ = statefulrepo
--- a/tests/run-tests.py Mon Jun 06 16:52:03 2011 +0200
+++ b/tests/run-tests.py Mon Jun 06 16:42:56 2011 +0200
@@ -277,8 +277,12 @@
return missing, failed
def showdiff(expected, output, ref, err):
- for line in difflib.unified_diff(expected, output, ref, err):
- sys.stdout.write(line)
+ try:
+ for line in difflib.unified_diff(expected, output, ref, err):
+ sys.stdout.write(line)
+ except IOError, ex:
+ print >>sys.stderr, 'BORKEN PIPE', ex.errno
+ pass
def findprogram(program):
"""Search PATH for a executable program"""
@@ -765,8 +769,12 @@
fail("returned error code %d" % ret)
if not options.verbose:
- sys.stdout.write(mark)
- sys.stdout.flush()
+ try:
+ sys.stdout.write(mark)
+ sys.stdout.flush()
+ except IOError, ex:
+ print >>sys.stderr, 'BORKEN PIPE', ex.errno
+ pass
killdaemons()
--- a/tests/test-draft.t Mon Jun 06 16:52:03 2011 +0200
+++ b/tests/test-draft.t Mon Jun 06 16:42:56 2011 +0200
@@ -30,7 +30,6 @@
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files
- $ hg publish 1 # until we fix push
$ echo "tree" >> savanna
$ hg add savanna
$ hg ci -m "terrain"
@@ -59,7 +58,7 @@
searching for changes
no changes found
[1]
- $ hg push ../remote1
+ $ hg push --traceback ../remote1
pushing to ../remote1
searching for changes
no changes found
@@ -101,7 +100,7 @@
comparing with ../local
0:5caa672bac26
1:710fe444b3b0
- $ hg pull ../local
+ $ hg pull ../local
pulling from ../local
requesting all changes
adding changesets
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-ready.t Mon Jun 06 16:42:56 2011 +0200
@@ -0,0 +1,129 @@
+ $ cat >> $HGRCPATH <<EOF
+ > [liquid]
+ > publish = False
+ > [extensions]
+ > graphlog=
+ > EOF
+ $ echo "states=$(echo $(dirname $TESTDIR))/states.py" >> $HGRCPATH
+
+ $ mkcommit() {
+ > echo "$1" > "$1"
+ > hg add "$1"
+ > hg ci -m "add $1"
+ > }
+
+ $ hg init alpha
+ $ cd alpha
+ $ cat > .hg/hgrc << EOF
+ > [states]
+ > ready=yes
+ > EOF
+ $ mkcommit z
+ $ mkcommit a
+ $ mkcommit b
+ $ mkcommit c
+ $ hg published 1
+ $ hg log --graph
+ @ changeset: 3:090483935bca
+ | tag: tip
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: add c
+ |
+ o changeset: 2:720fd97246d7
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: add b
+ |
+ o changeset: 1:7a344d213ee2
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: add a
+ |
+ o changeset: 0:d32fd17cb041
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: add z
+
+ $ cat .hg/states/published-heads
+ 7a344d213ee2eb3359d94630d4e076460d59dbf0
+
+publishedheads() should return only revision 1:
+ $ hg log -r 'publishedheads()' --graph
+ o changeset: 1:7a344d213ee2
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: add a
+ |
+
+ancestors of publishedheads shows all frozen revisions:
+ $ hg log -r '::publishedheads()' --graph
+ o changeset: 1:7a344d213ee2
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: add a
+ |
+ o changeset: 0:d32fd17cb041
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: add z
+
+ $ cd ..
+ $ hg init beta
+ $ cd beta
+ $ cat > .hg/hgrc << EOF
+ > [states]
+ > ready=yes
+ > EOF
+ $ hg pull ../alpha --update
+ pulling from ../alpha
+ requesting all changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 4 changesets with 4 changes to 4 files
+ 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg log --graph -r 'publishedheads()'
+ o changeset: 1:7a344d213ee2
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: add a
+ |
+
+Freeze in beta and push to alpha:
+ $ hg published 3
+ $ mkcommit d
+ $ hg push --traceback ../alpha
+ pushing to ../alpha
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 1 changes to 1 files
+ $ cd ../alpha
+ $ hg debugrevspec 'publishedheads()'
+ 3
+ $ hg log --graph -r 'publishedheads()'
+ @ changeset: 3:090483935bca
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: add c
+ |
+
+ $ hg log -r tip
+ changeset: 4:fb98f3f5bba0
+ tag: tip
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: add d
+
+ $ mkcommit e
+ created new head
+ $ hg up -C 4
+ 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ hg log -r 'publishedheads()'
+ changeset: 3:090483935bca
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: add c
+