Command for undoing an undo. Signed-off-by: Karl Hasselström <kha@xxxxxxxxxxx> --- stgit/commands/redo.py | 21 +++++++++------ stgit/lib/log.py | 21 ++++++++++++--- stgit/main.py | 2 + t/t3104-redo.sh | 66 +++++++++++++++++++++++++++++++++++++----------- 4 files changed, 81 insertions(+), 29 deletions(-) copy stgit/commands/{undo.py => redo.py} (71%) copy t/{t3102-undo.sh => t3104-redo.sh} (53%) diff --git a/stgit/commands/undo.py b/stgit/commands/redo.py similarity index 71% copy from stgit/commands/undo.py copy to stgit/commands/redo.py index b1d7de9..47221a5 100644 --- a/stgit/commands/undo.py +++ b/stgit/commands/redo.py @@ -19,28 +19,31 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from optparse import make_option from stgit.commands import common -from stgit.lib import git, log, transaction -from stgit.out import out +from stgit.lib import log, transaction -help = 'undo the last operation' +help = 'undo the last undo operation' usage = """%prog [options] -Reset the patch stack to the previous state. Consecutive invocations -of "stg undo" will take you ever further into the past.""" +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.""" directory = common.DirectoryHasRepositoryLib() options = [make_option('-n', '--number', type = 'int', metavar = 'N', default = 1, - help = 'undo the last N commands'), + help = 'undo the last N undos'), make_option('--hard', action = 'store_true', help = 'discard changes in your index/worktree')] def func(parser, options, args): stack = directory.repository.current_stack if options.number < 1: - raise common.CmdException('Bad number of commands to undo') - state = log.undo_state(stack, options.number) - trans = transaction.StackTransaction(stack, 'undo %d' % options.number, + 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, []) diff --git a/stgit/lib/log.py b/stgit/lib/log.py index 3b242cd..a8de06b 100644 --- a/stgit/lib/log.py +++ b/stgit/lib/log.py @@ -365,6 +365,8 @@ def undo_state(stack, undo_steps): 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{Log}""" @@ -374,13 +376,22 @@ def undo_state(stack, undo_steps): except KeyError: raise LogException('Log is empty') log = Log(stack.repository, ref, commit) - while undo_steps > 0: + while undo_steps != 0: msg = log.commit.data.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.parents: raise LogException('Not enough undo information available') log = Log(stack.repository, log.parents[0].sha1, log.parents[0]) diff --git a/stgit/main.py b/stgit/main.py index cf7b404..c53abf7 100644 --- a/stgit/main.py +++ b/stgit/main.py @@ -86,6 +86,7 @@ commands = Commands({ 'pull': 'pull', 'push': 'push', 'rebase': 'rebase', + 'redo': 'redo', 'refresh': 'refresh', 'rename': 'rename', 'repair': 'repair', @@ -123,6 +124,7 @@ stackcommands = ( 'pull', 'push', 'rebase', + 'redo', 'repair', 'reset', 'series', diff --git a/t/t3102-undo.sh b/t/t3104-redo.sh similarity index 53% copy from t/t3102-undo.sh copy to t/t3104-redo.sh index 1093f70..290fc6f 100755 --- a/t/t3102-undo.sh +++ b/t/t3104-redo.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='Simple test cases for "stg undo"' +test_description='Simple test cases for "stg redo"' . ./test-lib.sh @@ -20,18 +20,18 @@ test_expect_success 'Initialize StGit stack with three patches' ' git commit -a -m p2 && echo 333 >> a && git commit -a -m p3 && - stg uncommit -n 3 && - stg pop + stg uncommit -n 3 ' cat > expected.txt <<EOF 000 111 +222 EOF test_expect_success 'Pop one patch ...' ' stg pop && - test "$(echo $(stg applied))" = "p1" && - test "$(echo $(stg unapplied))" = "p2 p3" && + test "$(echo $(stg applied))" = "p1 p2" && + test "$(echo $(stg unapplied))" = "p3" && test_cmp expected.txt a ' @@ -39,9 +39,22 @@ cat > expected.txt <<EOF 000 111 222 +333 EOF -test_expect_success '... and undo it' ' +test_expect_success '... undo it ...' ' stg undo && + test "$(echo $(stg applied))" = "p1 p2 p3" && + test "$(echo $(stg unapplied))" = "" && + test_cmp expected.txt a +' + +cat > expected.txt <<EOF +000 +111 +222 +EOF +test_expect_success '... and redo' ' + stg redo && test "$(echo $(stg applied))" = "p1 p2" && test "$(echo $(stg unapplied))" = "p3" && test_cmp expected.txt a @@ -50,7 +63,9 @@ test_expect_success '... and undo it' ' cat > expected.txt <<EOF 000 EOF -test_expect_success 'Pop two patches ...' ' +test_expect_success 'Pop three patches ...' ' + stg push && + stg pop && stg pop && stg pop && test "$(echo $(stg applied))" = "" && @@ -62,24 +77,45 @@ cat > expected.txt <<EOF 000 111 222 +333 EOF -test_expect_success '... and undo it' ' +test_expect_success '... undo it ...' ' stg undo && stg undo && - test "$(echo $(stg applied))" = "p1 p2" && - test "$(echo $(stg unapplied))" = "p3" && + stg undo && + test "$(echo $(stg applied))" = "p1 p2 p3" && + test "$(echo $(stg unapplied))" = "" && test_cmp expected.txt a ' cat > expected.txt <<EOF 000 111 -222 EOF -test_expect_success 'Undo past end of history' ' - ! stg undo -n 100 && - test "$(echo $(stg applied))" = "p1 p2" && - test "$(echo $(stg unapplied))" = "p3" && +test_expect_success '... redo the first two pops ...' ' + stg redo -n 2 && + test "$(echo $(stg applied))" = "p1" && + test "$(echo $(stg unapplied))" = "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 applied))" = "" && + test "$(echo $(stg unapplied))" = "p1 p2 p3" && + test_cmp expected.txt a +' + +cat > expected.txt <<EOF +000 +EOF +test_expect_success 'Redo past end of history' ' + ! stg redo && + test "$(echo $(stg applied))" = "" && + test "$(echo $(stg unapplied))" = "p1 p2 p3" && test_cmp expected.txt a ' -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html