Check for top == head at the start of every transaction
authorKarl Hasselström <kha@treskal.com>
Sun, 21 Sep 2008 12:17:42 +0000 (14:17 +0200)
committerKarl Hasselström <kha@treskal.com>
Sun, 21 Sep 2008 12:19:07 +0000 (14:19 +0200)
We used to check it in the run() method, but that's sometimes too
late: for example, it causes stg coalesce to ask for a commit message
_before_ the check, resulting in a lost commit message if the check
fails.

As before, the check can be disabled for the few commands that need
it.

Signed-off-by: Karl Hasselström <kha@treskal.com>
stgit/commands/redo.py
stgit/commands/reset.py
stgit/commands/uncommit.py
stgit/commands/undo.py
stgit/lib/transaction.py
t/t2600-coalesce.sh

index 23478f6..8e62a1d 100644 (file)
@@ -46,7 +46,8 @@ def func(parser, options, args):
         raise common.CmdException('Bad number of undos to redo')
     state = log.undo_state(stack, -options.number)
     trans = transaction.StackTransaction(stack, 'redo %d' % options.number,
-                                         discard_changes = options.hard)
+                                         discard_changes = options.hard,
+                                         allow_bad_head = True)
     try:
         log.reset_stack(trans, stack.repository.default_iw, state)
     except transaction.TransactionHalted:
index eb1ab4e..a963d63 100644 (file)
@@ -59,7 +59,8 @@ def func(parser, options, args):
     else:
         raise common.CmdException('Wrong number of arguments')
     trans = transaction.StackTransaction(stack, 'reset',
-                                         discard_changes = options.hard)
+                                         discard_changes = options.hard,
+                                         allow_bad_head = True)
     try:
         if patches:
             log.reset_stack_partially(trans, stack.repository.default_iw,
index c44385d..b9950ca 100644 (file)
@@ -135,7 +135,8 @@ def func(parser, options, args):
         patchnames.reverse()
 
     trans = transaction.StackTransaction(stack, 'uncommit',
-                                         allow_conflicts = True)
+                                         allow_conflicts = True,
+                                         allow_bad_head = True)
     for commit, pn in zip(commits, patchnames):
         trans.patches[pn] = commit
     trans.applied = list(reversed(patchnames)) + trans.applied
index 12f5f6d..b7b1b73 100644 (file)
@@ -43,7 +43,8 @@ def func(parser, options, args):
         raise common.CmdException('Bad number of commands to undo')
     state = log.undo_state(stack, options.number)
     trans = transaction.StackTransaction(stack, 'undo %d' % options.number,
-                                         discard_changes = options.hard)
+                                         discard_changes = options.hard,
+                                         allow_bad_head = True)
     try:
         log.reset_stack(trans, stack.repository.default_iw, state)
     except transaction.TransactionHalted:
index 7c7139c..c6e2db3 100644 (file)
@@ -75,7 +75,7 @@ class StackTransaction(object):
       your refs and index+worktree, or fail without having done
       anything."""
     def __init__(self, stack, msg, discard_changes = False,
-                 allow_conflicts = False):
+                 allow_conflicts = False, allow_bad_head = False):
         """Create a new L{StackTransaction}.
 
         @param discard_changes: Discard any changes in index+worktree
@@ -99,6 +99,8 @@ class StackTransaction(object):
         else:
             self.__allow_conflicts = allow_conflicts
         self.__temp_index = self.temp_index_tree = None
+        if not allow_bad_head:
+            self.__assert_head_top_equal()
     stack = property(lambda self: self.__stack)
     patches = property(lambda self: self.__patches)
     def __set_applied(self, val):
@@ -137,13 +139,16 @@ class StackTransaction(object):
     def __set_head(self, val):
         self.__bad_head = val
     head = property(__get_head, __set_head)
-    def __checkout(self, tree, iw, allow_bad_head):
-        if not (allow_bad_head or self.__stack.head_top_equal()):
+    def __assert_head_top_equal(self):
+        if not self.__stack.head_top_equal():
             out.error(
                 'HEAD and top are not the same.',
                 'This can happen if you modify a branch with git.',
                 '"stg repair --help" explains more about what to do next.')
             self.__abort()
+    def __checkout(self, tree, iw, allow_bad_head):
+        if not allow_bad_head:
+            self.__assert_head_top_equal()
         if self.__current_tree == tree and not self.__discard_changes:
             # No tree change, but we still want to make sure that
             # there are no unresolved conflicts. Conflicts
index 33c073d..9a043fd 100755 (executable)
@@ -33,7 +33,7 @@ cat > editor <<EOF
 echo "Editor was invoked" | tee editor-invoked
 EOF
 chmod a+x editor
-test_expect_failure 'Coalesce with top != head' '
+test_expect_success 'Coalesce with top != head' '
     echo blahonga >> foo.txt &&
     git commit -a -m "a new commit" &&
     EDITOR=./editor command_error stg coalesce --name=r0 p0 q1 &&