From: "Karl Hasselström" <kha@treskal.com>
To: Catalin Marinas <catalin.marinas@gmail.com>
Cc: git@vger.kernel.org
Subject: [StGit PATCH 11/14] New command: stg undo
Date: Thu, 12 Jun 2008 07:35:13 +0200 [thread overview]
Message-ID: <20080612053513.23549.70063.stgit@yoghurt> (raw)
In-Reply-To: <20080612052913.23549.69687.stgit@yoghurt>
Basically, this is just a user-friendly way to access a subset of the
functionality of "stg reset".
Signed-off-by: Karl Hasselström <kha@treskal.com>
---
stgit/commands/undo.py | 40 +++++++---------------
stgit/lib/log.py | 38 +++++++++++++++++++++
stgit/main.py | 2 +
t/t3102-undo.sh | 86 +++++++++++++++++++++++++++++++++++++++++++++++
t/t3103-undo-hard.sh | 10 +++--
5 files changed, 144 insertions(+), 32 deletions(-)
copy stgit/commands/{reset.py => undo.py} (56%)
create mode 100755 t/t3102-undo.sh
copy t/{t3101-reset-hard.sh => t3103-undo-hard.sh} (82%)
diff --git a/stgit/commands/reset.py b/stgit/commands/undo.py
similarity index 56%
copy from stgit/commands/reset.py
copy to stgit/commands/undo.py
index 5ad9914..b1d7de9 100644
--- a/stgit/commands/reset.py
+++ b/stgit/commands/undo.py
@@ -22,42 +22,28 @@ from stgit.commands import common
from stgit.lib import git, log, transaction
from stgit.out import out
-help = 'reset the patch stack to an earlier state'
-usage = """%prog [options] <state> [<patchnames>]
+help = 'undo the last operation'
+usage = """%prog [options]
-Reset the patch stack to an earlier state. The state is specified with
-a commit from a stack log; for a branch foo, StGit stores the stack
-log in foo.stgit^. So to undo the last N StGit commands (or rather,
-the last N log entries; there is not an exact one-to-one
-relationship), you would say
-
- stg reset foo.stgit^~N
-
-or, if you are not sure how many steps to undo, you can view the log
-with "git log" or gitk
-
- gitk foo.stgit^
-
-and then reset to any sha1 you see in the log.
-
-If one or more patch names are given, reset only those patches, and
-leave the rest alone."""
+Reset the patch stack to the previous state. Consecutive invocations
+of "stg undo" will take you ever further into the past."""
directory = common.DirectoryHasRepositoryLib()
-options = [make_option('--hard', action = 'store_true',
+options = [make_option('-n', '--number', type = 'int', metavar = 'N',
+ default = 1,
+ help = 'undo the last N commands'),
+ make_option('--hard', action = 'store_true',
help = 'discard changes in your index/worktree')]
def func(parser, options, args):
stack = directory.repository.current_stack
- if len(args) >= 1:
- ref, patches = args[0], args[1:]
- state = log.Log(stack.repository, ref, stack.repository.rev_parse(ref))
- else:
- raise common.CmdException('Wrong number of arguments')
- trans = transaction.StackTransaction(stack, 'reset',
+ 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,
discard_changes = options.hard)
try:
- log.reset_stack(trans, stack.repository.default_iw, state, patches)
+ log.reset_stack(trans, stack.repository.default_iw, state, [])
except transaction.TransactionHalted:
pass
return trans.run(stack.repository.default_iw)
diff --git a/stgit/lib/log.py b/stgit/lib/log.py
index 2449913..3b242cd 100644
--- a/stgit/lib/log.py
+++ b/stgit/lib/log.py
@@ -95,6 +95,7 @@ except for the following:
The simplified log contains no information not in the full log; its
purpose is ease of visualization."""
+import re
from stgit.lib import git, stack
from stgit import exception
from stgit.out import out
@@ -258,6 +259,16 @@ class Log(object):
self.base = self.patches[self.applied[0]].data.parent
else:
self.base = self.head
+ @property
+ def top(self):
+ if self.applied:
+ return self.patches[self.applied[-1]]
+ else:
+ return self.head
+ @property
+ def parents(self):
+ num_refs = len(set([self.top, self.head]))
+ return self.commit.data.parents[(1 + num_refs):]
class FullLog(Log):
full_log = property(lambda self: self.commit)
@@ -347,3 +358,30 @@ def reset_stack(trans, iw, state, only_patches):
else:
# Recreate the exact order specified by the goal state.
trans.reorder_patches(state.applied, state.unapplied, iw)
+
+def undo_state(stack, undo_steps):
+ """Find the log entry C{undo_steps} steps in the past. (Successive
+ undo operations are supposed to "add up", so if we find other undo
+ operations along the way we have to add those undo steps to
+ C{undo_steps}.)
+
+ @return: The log entry that is the destination of the undo
+ operation
+ @rtype: L{Log}"""
+ ref = log_ref(stack.name)
+ try:
+ commit = stack.repository.refs.get(ref)
+ except KeyError:
+ raise LogException('Log is empty')
+ log = Log(stack.repository, ref, commit)
+ 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))
+ else:
+ undo_steps -= 1
+ if not log.parents:
+ raise LogException('Not enough undo information available')
+ log = Log(stack.repository, log.parents[0].sha1, log.parents[0])
+ return log
diff --git a/stgit/main.py b/stgit/main.py
index 83e6b08..cf7b404 100644
--- a/stgit/main.py
+++ b/stgit/main.py
@@ -99,6 +99,7 @@ commands = Commands({
'top': 'top',
'unapplied': 'unapplied',
'uncommit': 'uncommit',
+ 'undo': 'undo',
'unhide': 'unhide'
})
@@ -129,6 +130,7 @@ stackcommands = (
'top',
'unapplied',
'uncommit',
+ 'undo',
'unhide',
)
patchcommands = (
diff --git a/t/t3102-undo.sh b/t/t3102-undo.sh
new file mode 100755
index 0000000..1093f70
--- /dev/null
+++ b/t/t3102-undo.sh
@@ -0,0 +1,86 @@
+#!/bin/sh
+
+test_description='Simple test cases for "stg undo"'
+
+. ./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 &&
+ stg pop
+'
+
+cat > expected.txt <<EOF
+000
+111
+EOF
+test_expect_success 'Pop one patch ...' '
+ stg pop &&
+ test "$(echo $(stg applied))" = "p1" &&
+ test "$(echo $(stg unapplied))" = "p2 p3" &&
+ test_cmp expected.txt a
+'
+
+cat > expected.txt <<EOF
+000
+111
+222
+EOF
+test_expect_success '... and undo it' '
+ stg undo &&
+ test "$(echo $(stg applied))" = "p1 p2" &&
+ test "$(echo $(stg unapplied))" = "p3" &&
+ test_cmp expected.txt a
+'
+
+cat > expected.txt <<EOF
+000
+EOF
+test_expect_success 'Pop two patches ...' '
+ stg pop &&
+ stg pop &&
+ test "$(echo $(stg applied))" = "" &&
+ test "$(echo $(stg unapplied))" = "p1 p2 p3" &&
+ test_cmp expected.txt a
+'
+
+cat > expected.txt <<EOF
+000
+111
+222
+EOF
+test_expect_success '... and undo it' '
+ stg undo &&
+ stg undo &&
+ test "$(echo $(stg applied))" = "p1 p2" &&
+ test "$(echo $(stg unapplied))" = "p3" &&
+ 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_cmp expected.txt a
+'
+
+test_done
diff --git a/t/t3101-reset-hard.sh b/t/t3103-undo-hard.sh
similarity index 82%
copy from t/t3101-reset-hard.sh
copy to t/t3103-undo-hard.sh
index 1e02805..21412f7 100755
--- a/t/t3101-reset-hard.sh
+++ b/t/t3103-undo-hard.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-test_description='Simple test cases for "stg reset"'
+test_description='Simple test cases for "stg undo"'
. ./test-lib.sh
@@ -35,8 +35,8 @@ test_expect_success 'Pop middle patch, creating a conflict' '
test "$(echo $(stg unapplied))" = "p2"
'
-test_expect_success 'Try to reset without --hard' '
- ! stg reset master.stgit^~1 &&
+test_expect_success 'Try to undo without --hard' '
+ ! stg undo &&
stg status a > actual.txt &&
test_cmp expected.txt actual.txt &&
test "$(echo $(stg applied))" = "p1 p3" &&
@@ -45,8 +45,8 @@ test_expect_success 'Try to reset without --hard' '
cat > expected.txt <<EOF
EOF
-test_expect_success 'Try to reset with --hard' '
- stg reset --hard master.stgit^~1 &&
+test_expect_success 'Try to undo with --hard' '
+ stg undo --hard &&
stg status a > actual.txt &&
test_cmp expected.txt actual.txt &&
test "$(echo $(stg applied))" = "p1" &&
next prev parent reply other threads:[~2008-06-12 5:36 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-06-12 5:34 [StGit PATCH 00/14] Undo series Karl Hasselström
2008-06-12 5:34 ` [StGit PATCH 01/14] Fix typo Karl Hasselström
2008-06-12 5:34 ` [StGit PATCH 02/14] Library functions for tree and blob manipulation Karl Hasselström
2008-06-12 5:34 ` [StGit PATCH 03/14] Write to a stack log when stack is modified Karl Hasselström
2008-06-17 10:24 ` Catalin Marinas
2008-06-17 12:31 ` Karl Hasselström
2008-06-17 12:55 ` Karl Hasselström
2008-06-17 14:11 ` Catalin Marinas
2008-06-17 15:32 ` Karl Hasselström
2008-06-18 13:03 ` Catalin Marinas
2008-06-18 14:36 ` Karl Hasselström
2008-06-18 16:16 ` Catalin Marinas
2008-06-18 17:32 ` Karl Hasselström
2008-06-19 9:24 ` Catalin Marinas
2008-06-19 10:07 ` Karl Hasselström
2008-06-20 9:14 ` Catalin Marinas
2008-06-23 12:36 ` Karl Hasselström
2008-07-12 10:09 ` Catalin Marinas
2008-07-14 6:32 ` Karl Hasselström
2008-07-01 20:13 ` Karl Hasselström
2008-07-03 22:05 ` Catalin Marinas
2008-06-12 5:34 ` [StGit PATCH 04/14] Add utility function for reordering patches Karl Hasselström
2008-06-12 5:34 ` [StGit PATCH 05/14] New command: stg reset Karl Hasselström
2008-06-12 5:34 ` [StGit PATCH 06/14] Log conflicts separately Karl Hasselström
2008-06-12 5:34 ` [StGit PATCH 07/14] Log conflicts separately for all commands Karl Hasselström
2008-06-12 5:34 ` [StGit PATCH 08/14] Add a --hard flag to stg reset Karl Hasselström
2008-06-12 5:35 ` [StGit PATCH 09/14] Don't write a log entry if there were no changes Karl Hasselström
2008-06-12 5:35 ` [StGit PATCH 10/14] Move stack reset function to a shared location Karl Hasselström
2008-06-12 5:35 ` Karl Hasselström [this message]
2008-06-12 5:35 ` [StGit PATCH 12/14] New command: stg redo Karl Hasselström
2008-06-12 5:35 ` [StGit PATCH 13/14] Log and undo external modifications Karl Hasselström
2008-06-12 5:35 ` [StGit PATCH 14/14] Make "stg log" show stack log instead of patch log Karl Hasselström
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080612053513.23549.70063.stgit@yoghurt \
--to=kha@treskal.com \
--cc=catalin.marinas@gmail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).