]> git.ipfire.org Git - thirdparty/git.git/commitdiff
stash: allow "git stash -p <pathspec>" to assume push again
authorPhillip Wood <phillip.wood@dunelm.org.uk>
Sat, 7 Jun 2025 09:45:25 +0000 (10:45 +0100)
committerJunio C Hamano <gitster@pobox.com>
Sat, 7 Jun 2025 17:37:16 +0000 (10:37 -0700)
Historically "git stash [<options>]" was assumed to mean "git stash save
[<options>]". Since 1ada5020b38 (stash: use stash_push for no verb form,
2017-02-28) it is assumed to mean "git stash push [<options>]". As the
push subcommand supports pathspecs, 9e140909f61 (stash: allow pathspecs
in the no verb form, 2017-02-28) allowed "git stash -p <pathspec>" to
mean "git stash push -p <pathspec>". This was broken in 8c3713cede7
(stash: eliminate crude option parsing, 2020-02-17) which failed to
account for "push" being added to the start of argv in cmd_stash()
before it calls push_stash() and kept looking in argv[0] for "-p" after
moving the code to push_stash().

Fix this by regression by checking argv[1] instead of argv[0] and add a
couple of tests to prevent future regressions.

Helped-by: Martin Ă…gren <martin.agren@gmail.com>
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/stash.c
t/t3903-stash.sh

index cfbd92852a655700354286d4aa9c112e1f2dcf32..bc2c34fa048b9f7b3ac08edd3fc65214582af82d 100644 (file)
@@ -1789,7 +1789,7 @@ static int push_stash(int argc, const char **argv, const char *prefix,
        int ret;
 
        if (argc) {
-               force_assume = !strcmp(argv[0], "-p");
+               force_assume = argc > 1 && !strcmp(argv[1], "-p");
                argc = parse_options(argc, argv, prefix, options,
                                     push_assumed ? git_stash_usage :
                                     git_stash_push_usage,
index 74666ff3e4b2b8fa5aa9651e85dc7c82621bd304..a99a746221e5004bb91d724aacbc09794ad1545b 100755 (executable)
@@ -1177,6 +1177,28 @@ test_expect_success 'stash -- <pathspec> stashes and restores the file' '
        test_path_is_file bar
 '
 
+test_expect_success 'stash -p <pathspec> stash and restores the file' '
+       test_write_lines b c >file &&
+       git commit -m "add a few lines" file &&
+       test_write_lines a b c d >file &&
+       test_write_lines b c d >expect-file &&
+       echo changed-other-file >other-file &&
+       test_write_lines s y n | git stash -p file &&
+       test_cmp expect-file file &&
+       echo changed-other-file >expect &&
+       test_cmp expect other-file &&
+       git checkout HEAD -- file &&
+       git stash pop &&
+       test_cmp expect other-file &&
+       test_write_lines a b c >expect &&
+       test_cmp expect file
+'
+
+test_expect_success 'stash <pathspec> -p is rejected' '
+       test_must_fail git stash file -p 2>err &&
+       test_grep "subcommand wasn${SQ}t specified; ${SQ}push${SQ} can${SQ}t be assumed due to unexpected token ${SQ}file${SQ}" err
+'
+
 test_expect_success 'stash -- <pathspec> stashes in subdirectory' '
        mkdir sub &&
        >foo &&