Command for undoing an undo.
Signed-off-by: Karl Hasselström <kha@treskal.com>
--- /dev/null
+# -*- coding: utf-8 -*-
+
+__copyright__ = """
+Copyright (C) 2008, Karl Hasselström <kha@treskal.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+from stgit.argparse import opt
+from stgit.commands import common
+from stgit.lib import log, transaction
+
+help = 'Undo the last undo operation'
+kind = 'stack'
+usage = ['']
+description = """
+If the last command was an undo, reset the patch stack to the state it
+had before the undo. Consecutive invocations of "stg redo" will undo
+the effects of consecutive invocations of "stg undo".
+
+It is an error to run "stg redo" if the last command was not an
+undo."""
+
+options = [
+ opt('-n', '--number', type = 'int', metavar = 'N', default = 1,
+ short = 'Undo the last N undos'),
+ opt('--hard', action = 'store_true',
+ short = 'Discard changes in your index/worktree')]
+
+directory = common.DirectoryHasRepositoryLib()
+
+def func(parser, options, args):
+ stack = directory.repository.current_stack
+ if options.number < 1:
+ 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)
+ try:
+ log.reset_stack(trans, stack.repository.default_iw, state, [])
+ except transaction.TransactionHalted:
+ pass
+ return trans.run(stack.repository.default_iw)
operations along the way we have to add those undo steps to
C{undo_steps}.)
+ If C{undo_steps} is negative, redo instead of undo.
+
@return: The log entry that is the destination of the undo
operation
@rtype: L{LogEntry}"""
except KeyError:
raise LogException('Log is empty')
log = get_log_entry(stack.repository, ref, commit)
- while undo_steps > 0:
+ while undo_steps != 0:
msg = log.message.strip()
- m = re.match(r'^undo\s+(\d+)$', msg)
- if m:
- undo_steps += int(m.group(1))
+ um = re.match(r'^undo\s+(\d+)$', msg)
+ if undo_steps > 0:
+ if um:
+ undo_steps += int(um.group(1))
+ else:
+ undo_steps -= 1
else:
- undo_steps -= 1
+ rm = re.match(r'^redo\s+(\d+)$', msg)
+ if um:
+ undo_steps += 1
+ elif rm:
+ undo_steps -= int(rm.group(1))
+ else:
+ raise LogException('No more redo information available')
if not log.prev:
raise LogException('Not enough undo information available')
log = log.prev
--- /dev/null
+#!/bin/sh
+
+test_description='Simple test cases for "stg redo"'
+
+. ./test-lib.sh
+
+# Ignore our own output files.
+cat > .git/info/exclude <<EOF
+/expected.txt
+EOF
+
+test_expect_success 'Initialize StGit stack with three patches' '
+ stg init &&
+ echo 000 >> a &&
+ git add a &&
+ git commit -m a &&
+ echo 111 >> a &&
+ git commit -a -m p1 &&
+ echo 222 >> a &&
+ git commit -a -m p2 &&
+ echo 333 >> a &&
+ git commit -a -m p3 &&
+ stg uncommit -n 3
+'
+
+cat > expected.txt <<EOF
+000
+111
+222
+EOF
+test_expect_success 'Pop one patch ...' '
+ stg pop &&
+ test "$(echo $(stg series))" = "+ p1 > p2 - p3" &&
+ test_cmp expected.txt a
+'
+
+cat > expected.txt <<EOF
+000
+111
+222
+333
+EOF
+test_expect_success '... undo it ...' '
+ stg undo &&
+ test "$(echo $(stg series))" = "+ p1 + p2 > p3" &&
+ test_cmp expected.txt a
+'
+
+cat > expected.txt <<EOF
+000
+111
+222
+EOF
+test_expect_success '... and redo' '
+ stg redo &&
+ test "$(echo $(stg series))" = "+ p1 > p2 - p3" &&
+ test_cmp expected.txt a
+'
+
+cat > expected.txt <<EOF
+000
+EOF
+test_expect_success 'Pop three patches ...' '
+ stg push &&
+ stg pop &&
+ stg pop &&
+ stg pop &&
+ test "$(echo $(stg series))" = "- p1 - p2 - p3" &&
+ test_cmp expected.txt a
+'
+
+cat > expected.txt <<EOF
+000
+111
+222
+333
+EOF
+test_expect_success '... undo it ...' '
+ stg undo &&
+ stg undo &&
+ stg undo &&
+ test "$(echo $(stg series))" = "+ p1 + p2 > p3" &&
+ test_cmp expected.txt a
+'
+
+cat > expected.txt <<EOF
+000
+111
+EOF
+test_expect_success '... redo the first two pops ...' '
+ stg redo -n 2 &&
+ test "$(echo $(stg series))" = "> p1 - p2 - p3" &&
+ test_cmp expected.txt a
+'
+
+cat > expected.txt <<EOF
+000
+EOF
+test_expect_success '... and the remaining one' '
+ stg redo &&
+ test "$(echo $(stg series))" = "- p1 - p2 - p3" &&
+ test_cmp expected.txt a
+'
+
+cat > expected.txt <<EOF
+000
+EOF
+test_expect_success 'Redo past end of history' '
+ command_error stg redo &&
+ test "$(echo $(stg series))" = "- p1 - p2 - p3" &&
+ test_cmp expected.txt a
+'
+
+test_done