From: "Karl Hasselström" <kha@treskal.com>
To: Catalin Marinas <catalin.marinas@gmail.com>
Cc: git@vger.kernel.org
Subject: [StGit PATCH 08/14] Add a --hard flag to stg reset
Date: Thu, 12 Jun 2008 07:34:56 +0200 [thread overview]
Message-ID: <20080612053456.23549.41821.stgit@yoghurt> (raw)
In-Reply-To: <20080612052913.23549.69687.stgit@yoghurt>
With this flag, reset will overwrite any local changes. Useful e.g.
when undoing a push that has polluted the index+worktree with a heap
of conflicts.
Signed-off-by: Karl Hasselström <kha@treskal.com>
---
stgit/commands/reset.py | 13 +++++++----
stgit/lib/git.py | 4 +++
stgit/lib/transaction.py | 17 ++++++++++++--
t/t3101-reset-hard.sh | 56 ++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 82 insertions(+), 8 deletions(-)
create mode 100755 t/t3101-reset-hard.sh
diff --git a/stgit/commands/reset.py b/stgit/commands/reset.py
index b2643b1..a7b5d35 100644
--- a/stgit/commands/reset.py
+++ b/stgit/commands/reset.py
@@ -17,12 +17,13 @@ along with this program; if not, write to the Free Software
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
help = 'reset the patch stack to an earlier state'
-usage = """%prog <state> [<patchnames>]
+usage = """%prog [options] <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
@@ -43,9 +44,10 @@ If one or more patch names are given, reset only those patches, and
leave the rest alone."""
directory = common.DirectoryHasRepositoryLib()
-options = []
+options = [make_option('--hard', action = 'store_true',
+ help = 'discard changes in your index/worktree')]
-def reset_stack(stack, iw, state, only_patches):
+def reset_stack(stack, iw, state, only_patches, hard):
only_patches = set(only_patches)
def mask(s):
if only_patches:
@@ -55,7 +57,7 @@ def reset_stack(stack, iw, state, only_patches):
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')
+ trans = transaction.StackTransaction(stack, 'reset', discard_changes = hard)
# If we have to change the stack base, we need to pop all patches
# first.
@@ -113,4 +115,5 @@ def func(parser, options, args):
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)
+ return reset_stack(stack, stack.repository.default_iw, state, patches,
+ options.hard)
diff --git a/stgit/lib/git.py b/stgit/lib/git.py
index 35e03d2..4c2605b 100644
--- a/stgit/lib/git.py
+++ b/stgit/lib/git.py
@@ -736,6 +736,10 @@ class IndexAndWorktree(RunWithEnvCwd):
env = property(lambda self: utils.add_dict(self.__index.env,
self.__worktree.env))
cwd = property(lambda self: self.__worktree.directory)
+ def checkout_hard(self, tree):
+ assert isinstance(tree, Tree)
+ self.run(['git', 'read-tree', '--reset', '-u', tree.sha1]
+ ).discard_output()
def checkout(self, old_tree, new_tree):
# TODO: Optionally do a 3-way instead of doing nothing when we
# have a problem. Or maybe we should stash changes in a patch?
diff --git a/stgit/lib/transaction.py b/stgit/lib/transaction.py
index 6347b14..10c9b39 100644
--- a/stgit/lib/transaction.py
+++ b/stgit/lib/transaction.py
@@ -73,7 +73,14 @@ class StackTransaction(object):
method. This will either succeed in writing the updated state to
your refs and index+worktree, or fail without having done
anything."""
- def __init__(self, stack, msg, allow_conflicts = False):
+ def __init__(self, stack, msg, discard_changes = False,
+ allow_conflicts = False):
+ """Create a new L{StackTransaction}.
+
+ @param discard_changes: Discard any changes in index+worktree
+ @type discard_changes: bool
+ @param allow_conflicts: Whether to allow pre-existing conflicts
+ @type allow_conflicts: bool or function of L{StackTransaction}"""
self.__stack = stack
self.__msg = msg
self.__patches = _TransPatchMap(stack)
@@ -83,6 +90,7 @@ class StackTransaction(object):
self.__error = None
self.__current_tree = self.__stack.head.data.tree
self.__base = self.__stack.base
+ self.__discard_changes = discard_changes
if isinstance(allow_conflicts, bool):
self.__allow_conflicts = lambda trans: allow_conflicts
else:
@@ -107,7 +115,7 @@ class StackTransaction(object):
'This can happen if you modify a branch with git.',
'"stg repair --help" explains more about what to do next.')
self.__abort()
- if self.__current_tree == tree:
+ 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
# conceptually "belong" to the topmost patch, and just
@@ -118,7 +126,10 @@ class StackTransaction(object):
out.error('Need to resolve conflicts first')
self.__abort()
assert iw != None
- iw.checkout(self.__current_tree, tree)
+ if self.__discard_changes:
+ iw.checkout_hard(tree)
+ else:
+ iw.checkout(self.__current_tree, tree)
self.__current_tree = tree
@staticmethod
def __abort():
diff --git a/t/t3101-reset-hard.sh b/t/t3101-reset-hard.sh
new file mode 100755
index 0000000..1e02805
--- /dev/null
+++ b/t/t3101-reset-hard.sh
@@ -0,0 +1,56 @@
+#!/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
+/actual.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
+C a
+EOF
+test_expect_success 'Pop middle patch, creating a conflict' '
+ ! stg pop p2 &&
+ stg status a > actual.txt &&
+ test_cmp expected.txt actual.txt &&
+ test "$(echo $(stg applied))" = "p1 p3" &&
+ test "$(echo $(stg unapplied))" = "p2"
+'
+
+test_expect_success 'Try to reset without --hard' '
+ ! stg reset master.stgit^~1 &&
+ stg status a > actual.txt &&
+ test_cmp expected.txt actual.txt &&
+ test "$(echo $(stg applied))" = "p1 p3" &&
+ test "$(echo $(stg unapplied))" = "p2"
+'
+
+cat > expected.txt <<EOF
+EOF
+test_expect_success 'Try to reset with --hard' '
+ stg reset --hard master.stgit^~1 &&
+ stg status a > actual.txt &&
+ test_cmp expected.txt actual.txt &&
+ test "$(echo $(stg applied))" = "p1" &&
+ test "$(echo $(stg unapplied))" = "p3 p2"
+'
+
+test_done
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 ` Karl Hasselström [this message]
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=20080612053456.23549.41821.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).