[states] make disabling state saftier
authorAlain Leufroy <alain.leufroy@logilab.fr>
Thu, 22 Sep 2011 19:18:40 +0200
changeset 97 e672cb1263cb
parent 96 d5170cc7881c
child 98 8ad5c760c708
[states] make disabling state saftier It is not allowed to disable a state that is not empty because "Explicit is better than implicit". A hint is displayed to help the user.
hgext/states.py
tests/test-draft.t
--- a/hgext/states.py	Sun Sep 25 12:43:00 2011 +0200
+++ b/hgext/states.py	Thu Sep 22 19:18:40 2011 +0200
@@ -517,7 +517,7 @@
                 return 1
             if off:
                 if st in repo._enabledstates:
-                    repo._enabledstates.remove(st)
+                    repo.disablestate(st)
                 else:
                     ui.write_err(_('state %s already deactivated\n') %
                                  state_name)
@@ -786,7 +786,24 @@
                         break
             return state
 
-
+        def disablestate(self, state):
+            """Disable empty state.
+            Raise error.Abort if the state is not empty.
+            """
+            # the lowest is mandatory
+            if state == ST0:
+                raise error.Abort(_('could not disable %s' % state.name))
+            enabled =  self._enabledstates
+            # look up for lower state that is enabled (at least published)
+            lower = max(st for st in self._enabledstates if st < state)
+            if repo.stateheads(state) != repo.stateheads(lower):
+                raise error.Abort(
+                    _('could not disable non empty state %s' % state.name),
+                    hint=_("You may want to use `hg %s '%sheads()'`"
+                            % (lower.name, state.name))
+                    )
+            else:
+                enabled.remove(state)
 
         def stateheads(self, state):
             """Return the set of head that define the state"""
--- a/tests/test-draft.t	Sun Sep 25 12:43:00 2011 +0200
+++ b/tests/test-draft.t	Thu Sep 22 19:18:40 2011 +0200
@@ -75,6 +75,10 @@
 
 turn draft off again (repo side)
   $ hg states --off draft
+  abort: could not disable non empty state draft
+  (You may want to use `hg published 'draftheads()'`)
+  [255]
+  $ hg published tip
   $ hg log --template='{rev}:{node|short}: {state}\n'
   3:73585b17392a: published
   2:3c8695235a32: published
@@ -88,6 +92,7 @@
 
 turn draft on again (repo side)
   $ hg states draft
+  $ hg draft --exact 2
 
 test incoming and pull
 
@@ -164,6 +169,11 @@
   $ cd ..
   $ "$TESTDIR/killdaemons.py"
   $ hg -R local states --off draft
+  abort: could not disable non empty state draft
+  (You may want to use `hg published 'draftheads()'`)
+  [255]
+  $ hg -R local published tip
+  $ hg -R local states --off draft
   $ hg -R local serve -p $HGPORT -d --pid-file=local.pid
   $ cat local.pid >> "$DAEMON_PIDS"
   $ cd fromhttp2
@@ -195,11 +205,13 @@
   searching for changes
   0:5caa672bac26
   1:710fe444b3b0
+  2:3c8695235a32
+  3:73585b17392a
   $ hg push http://localhost:$HGPORT/
   pushing to http://localhost:$HGPORT/
   searching for changes
   remote: adding changesets
   remote: adding manifests
   remote: adding file changes
-  remote: added 2 changesets with 2 changes to 1 files
+  remote: added 4 changesets with 4 changes to 2 files
   $ "$TESTDIR/killdaemons.py"