stash: fix show referencing stash index
In the conversion of 'stash show' to C in dc7bd382b1
("stash: convert
show to builtin", 2019-02-25), 'git stash show <n>', where n is the
index of a stash got broken, if n is not a file or a valid revision by
itself.
'stash show' accepts any flag 'git diff' accepts for changing the
output format. Internally we use 'setup_revisions()' to parse these
command line flags. Currently we pass the whole argv through to
'setup_revisions()', which includes the stash index.
As the stash index is not a valid revision or a file in the working
tree in most cases however, this 'setup_revisions()' call (and thus
the whole command) ends up failing if we use this form of 'git stash
show'.
Instead of passing the whole argv to 'setup_revisions()', only pass
the flags (and the command name) through, while excluding the stash
reference. The stash reference is parsed (and validated) in
'get_stash_info()' already.
This separate parsing also means that we currently do produce the
correct output if the command succeeds.
Reported-by: Mike Hommey <mh@glandium.org>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
b697d92f56
commit
63b50c8ffe
@ -713,11 +713,11 @@ static int git_stash_config(const char *var, const char *value, void *cb)
|
|||||||
static int show_stash(int argc, const char **argv, const char *prefix)
|
static int show_stash(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int opts = 0;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct stash_info info;
|
struct stash_info info;
|
||||||
struct rev_info rev;
|
struct rev_info rev;
|
||||||
struct argv_array stash_args = ARGV_ARRAY_INIT;
|
struct argv_array stash_args = ARGV_ARRAY_INIT;
|
||||||
|
struct argv_array revision_args = ARGV_ARRAY_INIT;
|
||||||
struct option options[] = {
|
struct option options[] = {
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
@ -726,11 +726,12 @@ static int show_stash(int argc, const char **argv, const char *prefix)
|
|||||||
git_config(git_diff_ui_config, NULL);
|
git_config(git_diff_ui_config, NULL);
|
||||||
init_revisions(&rev, prefix);
|
init_revisions(&rev, prefix);
|
||||||
|
|
||||||
|
argv_array_push(&revision_args, argv[0]);
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
if (argv[i][0] != '-')
|
if (argv[i][0] != '-')
|
||||||
argv_array_push(&stash_args, argv[i]);
|
argv_array_push(&stash_args, argv[i]);
|
||||||
else
|
else
|
||||||
opts++;
|
argv_array_push(&revision_args, argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = get_stash_info(&info, stash_args.argc, stash_args.argv);
|
ret = get_stash_info(&info, stash_args.argc, stash_args.argv);
|
||||||
@ -742,7 +743,7 @@ static int show_stash(int argc, const char **argv, const char *prefix)
|
|||||||
* The config settings are applied only if there are not passed
|
* The config settings are applied only if there are not passed
|
||||||
* any options.
|
* any options.
|
||||||
*/
|
*/
|
||||||
if (!opts) {
|
if (revision_args.argc == 1) {
|
||||||
git_config(git_stash_config, NULL);
|
git_config(git_stash_config, NULL);
|
||||||
if (show_stat)
|
if (show_stat)
|
||||||
rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT;
|
rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT;
|
||||||
@ -756,7 +757,7 @@ static int show_stash(int argc, const char **argv, const char *prefix)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
argc = setup_revisions(argc, argv, &rev, NULL);
|
argc = setup_revisions(revision_args.argc, revision_args.argv, &rev, NULL);
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
free_stash_info(&info);
|
free_stash_info(&info);
|
||||||
usage_with_options(git_stash_show_usage, options);
|
usage_with_options(git_stash_show_usage, options);
|
||||||
|
@ -708,6 +708,24 @@ test_expect_success 'invalid ref of the form "n", n >= N' '
|
|||||||
git stash drop
|
git stash drop
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'valid ref of the form "n", n < N' '
|
||||||
|
git stash clear &&
|
||||||
|
echo bar5 >file &&
|
||||||
|
echo bar6 >file2 &&
|
||||||
|
git add file2 &&
|
||||||
|
git stash &&
|
||||||
|
git stash show 0 &&
|
||||||
|
git stash branch tmp 0 &&
|
||||||
|
git checkout master &&
|
||||||
|
git stash &&
|
||||||
|
git stash apply 0 &&
|
||||||
|
git reset --hard &&
|
||||||
|
git stash pop 0 &&
|
||||||
|
git stash &&
|
||||||
|
git stash drop 0 &&
|
||||||
|
test_must_fail git stash drop
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'branch: do not drop the stash if the branch exists' '
|
test_expect_success 'branch: do not drop the stash if the branch exists' '
|
||||||
git stash clear &&
|
git stash clear &&
|
||||||
echo foo >file &&
|
echo foo >file &&
|
||||||
|
Loading…
Reference in New Issue
Block a user