changeset 9:1f84a74df837

introduce a third state
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Mon, 23 May 2011 17:15:47 +0200
parents e56e40db3225
children 91169d2d7f1b
files states.py tests/test-private.t
diffstat 2 files changed, 49 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- 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