From: Phillip Wood <phillip.wood@xxxxxxxxxxxxx> 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. Signed-off-by: Phillip Wood <phillip.wood@xxxxxxxxxxxxx> --- builtin/stash.c | 2 +- t/t3903-stash.sh | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/builtin/stash.c b/builtin/stash.c index cfbd92852a6..bc2c34fa048 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -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, diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 74666ff3e4b..d24559a328d 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -1177,6 +1177,25 @@ 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' ' + cat file >expect-file && + echo changed-file >file && + echo changed-other-file >other-file && + echo a | git stash -p file && + test_cmp expect-file file && + echo changed-other-file >expect && + test_cmp expect other-file && + git stash pop && + test_cmp expect other-file && + echo changed-file >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 && -- 2.49.0.897.gfad3eb7d210