stash: require a clean index to apply
authorJeff King <peff@peff.net>
Wed, 22 Apr 2015 19:31:02 +0000 (15:31 -0400)
committerJunio C Hamano <gitster@pobox.com>
Wed, 22 Apr 2015 20:38:58 +0000 (13:38 -0700)
If you have staged contents in your index and run "stash
apply", we may hit a conflict and put new entries into the
index. Recovering to your original state is difficult at
that point, because tools like "git reset --keep" will blow
away anything staged. We can make this safer by refusing to
apply when there are staged changes.

It's possible we could provide better tooling here, as "git
stash apply" should be writing only conflicts to the index
(so we know that any stage-0 entries are potentially
precious). But it is the odd duck; most "mergy" commands
will update the index for cleanly merged entries, and it is
not worth updating our tooling to support this use case
which is unlikely to be of interest (besides which, we would
still need to block a dirty index for "stash apply --index",
since that case _would_ be ambiguous).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
git-stash.sh
t/t3903-stash.sh
index d4cf818be9488f1b94fdf4766a8f73db6bfd1029..cc28368b01fc218f32ae98c21cce4d7f84c68eb0 100755 (executable)
@@ -442,6 +442,8 @@ apply_stash () {
        assert_stash_like "$@"
 
        git update-index -q --refresh || die "$(gettext "unable to refresh index")"
+       git diff-index --cached --quiet --ignore-submodules HEAD -- ||
+               die "$(gettext "Cannot apply stash: Your index contains uncommitted changes.")"
 
        # current index state
        c_tree=$(git write-tree) ||
index f179c93ddfade2034273ab15ad2054c36ad313b2..0746eeeff70c29c91accacdfa1efa4bc2e612715 100755 (executable)
@@ -45,6 +45,13 @@ test_expect_success 'applying bogus stash does nothing' '
        test_cmp expect file
 '
 
+test_expect_success 'apply requires a clean index' '
+       test_when_finished "git reset --hard" &&
+       echo changed >other-file &&
+       git add other-file &&
+       test_must_fail git stash apply
+'
+
 test_expect_success 'apply does not need clean working directory' '
        echo 4 >other-file &&
        git stash apply &&