Skip to content

Commit b932f6a

Browse files
tgummerergitster
authored andcommitted
stash: fix handling removed files with --keep-index
git stash push --keep-index is supposed to keep all changes that have been added to the index, both in the index and on disk. Currently this doesn't behave correctly when a file is removed from the index. Instead of keeping it deleted on disk, --keep-index currently restores the file. Fix that behaviour by using 'git checkout' in no-overlay mode which can faithfully restore the index and working tree. This also simplifies the code. Note that this will overwrite untracked files if the untracked file has the same name as a file that has been deleted in the index. Signed-off-by: Thomas Gummerer <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b697d92 commit b932f6a

File tree

2 files changed

+16
-23
lines changed

2 files changed

+16
-23
lines changed

builtin/stash.c

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,30 +1390,16 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
13901390
}
13911391

13921392
if (keep_index == 1 && !is_null_oid(&info.i_tree)) {
1393-
struct child_process cp_ls = CHILD_PROCESS_INIT;
1394-
struct child_process cp_checkout = CHILD_PROCESS_INIT;
1395-
struct strbuf out = STRBUF_INIT;
1396-
1397-
if (reset_tree(&info.i_tree, 0, 1)) {
1398-
ret = -1;
1399-
goto done;
1400-
}
1401-
1402-
cp_ls.git_cmd = 1;
1403-
argv_array_pushl(&cp_ls.args, "ls-files", "-z",
1404-
"--modified", "--", NULL);
1405-
1406-
add_pathspecs(&cp_ls.args, ps);
1407-
if (pipe_command(&cp_ls, NULL, 0, &out, 0, NULL, 0)) {
1408-
ret = -1;
1409-
goto done;
1410-
}
1393+
struct child_process cp = CHILD_PROCESS_INIT;
14111394

1412-
cp_checkout.git_cmd = 1;
1413-
argv_array_pushl(&cp_checkout.args, "checkout-index",
1414-
"-z", "--force", "--stdin", NULL);
1415-
if (pipe_command(&cp_checkout, out.buf, out.len, NULL,
1416-
0, NULL, 0)) {
1395+
cp.git_cmd = 1;
1396+
argv_array_pushl(&cp.args, "checkout", "--no-overlay",
1397+
oid_to_hex(&info.i_tree), "--", NULL);
1398+
if (!ps->nr)
1399+
argv_array_push(&cp.args, ":/");
1400+
else
1401+
add_pathspecs(&cp.args, ps);
1402+
if (run_command(&cp)) {
14171403
ret = -1;
14181404
goto done;
14191405
}

t/t3903-stash.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,4 +1216,11 @@ test_expect_success 'stash works when user.name and user.email are not set' '
12161216
)
12171217
'
12181218

1219+
test_expect_success 'stash --keep-index with file deleted in index does not resurrect it on disk' '
1220+
test_commit to-remove to-remove &&
1221+
git rm to-remove &&
1222+
git stash --keep-index &&
1223+
test_path_is_missing to-remove
1224+
'
1225+
12191226
test_done

0 commit comments

Comments
 (0)