# -O/--diff-opts). For example, -M turns on rename detection.
#diff-opts = -M
+ # Behave as if the --keep option is always passed
+ #autokeep = no
+
[mail "alias"]
# E-mail aliases used with the 'mail' command
git = git@vger.kernel.org
def author_options():
return _person_opts('author', 'auth')
+def keep_option():
+ return [opt('-k', '--keep', action = 'store_true',
+ short = 'Keep the local changes',
+ default = config.get('stgit.autokeep') == 'yes')]
+
class CompgenBase(object):
def actions(self, var): return set()
def words(self, var): return set()
from stgit.commands import common
from stgit.lib import transaction
from stgit import argparse
+from stgit.argparse import opt
help = 'Push or pop patches to the given one'
kind = 'stack'
line becomes current."""
args = [argparse.other_applied_patches, argparse.unapplied_patches]
-options = []
+options = argparse.keep_option()
directory = common.DirectoryHasRepositoryLib()
stack = directory.repository.current_stack
iw = stack.repository.default_iw
- trans = transaction.StackTransaction(stack, 'goto')
+ clean_iw = (not options.keep and iw) or None
+ trans = transaction.StackTransaction(stack, 'goto',
+ check_clean_iw = clean_iw)
if patch in trans.applied:
to_pop = set(trans.applied[trans.applied.index(patch)+1:])
assert not trans.pop_patches(lambda pn: pn in to_pop)
).output_one_line())
except run.RunException:
raise MergeException('Conflicting merge')
- def is_clean(self):
+ def is_clean(self, tree):
+ """Check whether the index is clean relative to the given treeish."""
try:
- self.run(['git', 'update-index', '--refresh']).discard_output()
+ self.run(['git', 'diff-index', '--quiet', '--cached', tree.sha1]
+ ).discard_output()
except run.RunException:
return False
else:
cmd = ['git', 'update-index', '--remove']
self.run(cmd + ['-z', '--stdin']
).input_nulterm(paths).discard_output()
+ def worktree_clean(self):
+ """Check whether the worktree is clean relative to index."""
+ try:
+ self.run(['git', 'update-index', '--refresh']).discard_output()
+ except run.RunException:
+ return False
+ else:
+ return True
class Branch(object):
"""Represents a Git branch."""
your refs and index+worktree, or fail without having done
anything."""
def __init__(self, stack, msg, discard_changes = False,
- allow_conflicts = False, allow_bad_head = False):
+ allow_conflicts = False, allow_bad_head = False,
+ check_clean_iw = None):
"""Create a new L{StackTransaction}.
@param discard_changes: Discard any changes in index+worktree
self.__temp_index = self.temp_index_tree = None
if not allow_bad_head:
self.__assert_head_top_equal()
+ if check_clean_iw:
+ self.__assert_index_worktree_clean(check_clean_iw)
stack = property(lambda self: self.__stack)
patches = property(lambda self: self.__patches)
def __set_applied(self, val):
'This can happen if you modify a branch with git.',
'"stg repair --help" explains more about what to do next.')
self.__abort()
+ def __assert_index_worktree_clean(self, iw):
+ if not iw.worktree_clean():
+ self.__halt('Worktree not clean. Use "refresh" or "status --reset"')
+ if not iw.index.is_clean(self.stack.head):
+ self.__halt('Index not clean. Use "refresh" or "status --reset"')
def __checkout(self, tree, iw, allow_bad_head):
if not allow_bad_head:
self.__assert_head_top_equal()
test_expect_success 'refresh an unapplied patch' '
stg refresh -u &&
- stg goto p0 &&
+ stg goto --keep p0 &&
test "$(stg status)" = "M foo.txt" &&
stg refresh -p p1 &&
test "$(stg status)" = "" &&
bar
EOF
test_expect_success 'Goto in subdirectory (just pop)' '
- (cd foo && stg goto p1) &&
+ (cd foo && stg goto --keep p1) &&
cat foo/bar > actual.txt &&
test_cmp expected1.txt actual.txt &&
ls foo > actual.txt &&
bar
EOF
test_expect_success 'Goto in subdirectory (conflicting push)' '
- (cd foo && stg goto p3) ;
+ (cd foo && stg goto --keep p3) ;
[ $? -eq 3 ] &&
cat foo/bar > actual.txt &&
test_cmp expected1.txt actual.txt &&
echo 4 > a &&
[ "$(echo $(stg series --applied --noprefix))" = "p1" ] &&
[ "$(echo $(stg series --unapplied --noprefix))" = "p2" ] &&
- conflict stg goto p2 &&
+ conflict stg goto --keep p2 &&
[ "$(echo $(stg series --applied --noprefix))" = "p1" ] &&
[ "$(echo $(stg series --unapplied --noprefix))" = "p2" ] &&
[ "$(echo $(cat a))" = "4" ]