From: "Karl Hasselström" <kha@treskal.com>
To: Catalin Marinas <catalin.marinas@gmail.com>
Cc: git@vger.kernel.org
Subject: [StGit PATCH 05/14] New command: stg reset
Date: Thu, 12 Jun 2008 07:34:38 +0200 [thread overview]
Message-ID: <20080612053438.23549.85715.stgit@yoghurt> (raw)
In-Reply-To: <20080612052913.23549.69687.stgit@yoghurt>
Given a commit object from the log, resets the stack (or just the
named patches) to the state given by that log entry.
Signed-off-by: Karl Hasselström <kha@treskal.com>
---
stgit/commands/reset.py | 116 ++++++++++++++++++++++++++++++++++++
stgit/main.py | 2 +
t/t3100-reset.sh | 151 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 269 insertions(+), 0 deletions(-)
create mode 100644 stgit/commands/reset.py
create mode 100755 t/t3100-reset.sh
diff --git a/stgit/commands/reset.py b/stgit/commands/reset.py
new file mode 100644
index 0000000..b2643b1
--- /dev/null
+++ b/stgit/commands/reset.py
@@ -0,0 +1,116 @@
+# -*- 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.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 <state> [<patchnames>]
+
+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."""
+
+directory = common.DirectoryHasRepositoryLib()
+options = []
+
+def reset_stack(stack, iw, state, only_patches):
+ only_patches = set(only_patches)
+ def mask(s):
+ if only_patches:
+ return s & only_patches
+ else:
+ return s
+ patches_to_reset = mask(set(state.applied + state.unapplied))
+ existing_patches = set(stack.patchorder.all)
+ to_delete = mask(existing_patches - patches_to_reset)
+ trans = transaction.StackTransaction(stack, 'reset')
+
+ # If we have to change the stack base, we need to pop all patches
+ # first.
+ if not only_patches and trans.base != state.base:
+ trans.pop_patches(lambda pn: True)
+ out.info('Setting stack base to %s' % state.base.sha1)
+ trans.base = state.base
+
+ # In one go, do all the popping we have to in order to pop the
+ # patches we're going to delete or modify.
+ def mod(pn):
+ if only_patches and not pn in only_patches:
+ return False
+ if pn in to_delete:
+ return True
+ if stack.patches.get(pn).commit != state.patches.get(pn, None):
+ return True
+ return False
+ trans.pop_patches(mod)
+
+ # Delete and modify/create patches. We've previously popped all
+ # patches that we touch in this step.
+ trans.delete_patches(lambda pn: pn in to_delete)
+ for pn in patches_to_reset:
+ if pn in existing_patches:
+ if trans.patches[pn] == state.patches[pn]:
+ continue
+ else:
+ out.info('Resetting %s' % pn)
+ else:
+ trans.unapplied.append(pn)
+ out.info('Resurrecting %s' % pn)
+ trans.patches[pn] = state.patches[pn]
+
+ # Push/pop patches as necessary.
+ try:
+ if only_patches:
+ # Push all the patches that we've popped, if they still
+ # exist.
+ pushable = set(trans.unapplied)
+ for pn in stack.patchorder.applied:
+ if pn in pushable:
+ trans.push_patch(pn, iw)
+ else:
+ # Recreate the exact order specified by the goal state.
+ trans.reorder_patches(state.applied, state.unapplied, iw)
+ except transaction.TransactionHalted:
+ pass
+ return trans.run(iw)
+
+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')
+ return reset_stack(stack, stack.repository.default_iw, state, patches)
diff --git a/stgit/main.py b/stgit/main.py
index ec0e840..83e6b08 100644
--- a/stgit/main.py
+++ b/stgit/main.py
@@ -89,6 +89,7 @@ commands = Commands({
'refresh': 'refresh',
'rename': 'rename',
'repair': 'repair',
+ 'reset': 'reset',
'resolved': 'resolved',
'series': 'series',
'show': 'show',
@@ -122,6 +123,7 @@ stackcommands = (
'push',
'rebase',
'repair',
+ 'reset',
'series',
'sink',
'top',
diff --git a/t/t3100-reset.sh b/t/t3100-reset.sh
new file mode 100755
index 0000000..1805091
--- /dev/null
+++ b/t/t3100-reset.sh
@@ -0,0 +1,151 @@
+#!/bin/sh
+
+test_description='Simple test cases for "stg reset"'
+
+. ./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 reset master.stgit^~1 &&
+ test "$(echo $(stg applied))" = "p1 p2" &&
+ test "$(echo $(stg unapplied))" = "p3" &&
+ test_cmp expected.txt a
+'
+
+cat > expected.txt <<EOF
+000
+111
+222
+333
+EOF
+test_expect_success 'Push one patch ...' '
+ stg push &&
+ 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 undo it' '
+ stg reset master.stgit^~1 &&
+ test "$(echo $(stg applied))" = "p1 p2" &&
+ test "$(echo $(stg unapplied))" = "p3" &&
+ test_cmp expected.txt a
+'
+
+test_expect_success 'Commit one patch ...' '
+ stg commit &&
+ test "$(echo $(stg applied))" = "p2" &&
+ test "$(echo $(stg unapplied))" = "p3"
+'
+
+test_expect_success '... and undo it' '
+ stg reset master.stgit^~1 &&
+ test "$(echo $(stg applied))" = "p1 p2" &&
+ test "$(echo $(stg unapplied))" = "p3"
+'
+
+cat > expected.txt <<EOF
+000
+111
+EOF
+test_expect_success 'Delete two patches ...' '
+ stg delete p2 p3 &&
+ test "$(echo $(stg applied))" = "p1" &&
+ test "$(echo $(stg unapplied))" = "" &&
+ test_cmp expected.txt a
+'
+
+test_expect_success '... and undo one of the deletions ...' '
+ stg reset master.stgit^~1 p3 &&
+ test "$(echo $(stg applied))" = "p1" &&
+ test "$(echo $(stg unapplied))" = "p3" &&
+ test_cmp expected.txt a
+'
+
+test_expect_success '... then undo the first undo ...' '
+ stg reset master.stgit^~1 &&
+ test "$(echo $(stg applied))" = "p1" &&
+ test "$(echo $(stg unapplied))" = "" &&
+ test_cmp expected.txt a
+'
+
+cat > expected.txt <<EOF
+000
+111
+222
+EOF
+test_expect_success '... and undo the other deletion' '
+ stg reset master.stgit^~3 p2 &&
+ stg push p2 &&
+ test "$(echo $(stg applied))" = "p1 p2" &&
+ test "$(echo $(stg unapplied))" = "" &&
+ test_cmp expected.txt a
+'
+
+cat > expected.txt <<EOF
+000
+111
+222
+ggg
+EOF
+test_expect_success 'Refresh a patch ...' '
+ echo ggg >> a &&
+ stg refresh &&
+ test "$(echo $(stg applied))" = "p1 p2" &&
+ test "$(echo $(stg unapplied))" = "" &&
+ test_cmp expected.txt a
+'
+
+cat > expected.txt <<EOF
+000
+111
+222
+EOF
+test_expect_success '... and undo the refresh' '
+ stg reset master.stgit^~1 &&
+ test "$(echo $(stg applied))" = "p1 p2" &&
+ test "$(echo $(stg unapplied))" = "" &&
+ test_cmp expected.txt a
+'
+
+test_done
next prev parent reply other threads:[~2008-06-12 5:35 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 ` Karl Hasselström [this message]
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 ` [StGit PATCH 11/14] New command: stg undo Karl Hasselström
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=20080612053438.23549.85715.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).