Skip to content

Commit 9ca7249

Browse files
committed
Merge branch 'mm/verify-filename-fix' into maint
"git diff COPYING HEAD:COPYING" gave a nonsense error message that claimed that the treeish HEAD did not have COPYING in it. * mm/verify-filename-fix: verify_filename(): ask the caller to chose the kind of diagnosis sha1_name: do not trigger detailed diagnosis for file arguments
2 parents a0ceb72 + 023e37c commit 9ca7249

File tree

8 files changed

+44
-10
lines changed

8 files changed

+44
-10
lines changed

builtin/grep.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
928928
if (!seen_dashdash) {
929929
int j;
930930
for (j = i; j < argc; j++)
931-
verify_filename(prefix, argv[j]);
931+
verify_filename(prefix, argv[j], j == i);
932932
}
933933

934934
paths = get_pathspec(prefix, argv + i);

builtin/reset.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
285285
rev = argv[i++];
286286
} else {
287287
/* Otherwise we treat this as a filename */
288-
verify_filename(prefix, argv[i]);
288+
verify_filename(prefix, argv[i], 1);
289289
}
290290
}
291291

builtin/rev-parse.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
486486

487487
if (as_is) {
488488
if (show_file(arg) && as_is < 2)
489-
verify_filename(prefix, arg);
489+
verify_filename(prefix, arg, 0);
490490
continue;
491491
}
492492
if (!strcmp(arg,"-n")) {
@@ -734,7 +734,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
734734
as_is = 1;
735735
if (!show_file(arg))
736736
continue;
737-
verify_filename(prefix, arg);
737+
verify_filename(prefix, arg, 1);
738738
}
739739
if (verify) {
740740
if (revs_count == 1) {

cache.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,9 @@ extern const char *setup_git_directory(void);
409409
extern char *prefix_path(const char *prefix, int len, const char *path);
410410
extern const char *prefix_filename(const char *prefix, int len, const char *path);
411411
extern int check_filename(const char *prefix, const char *name);
412-
extern void verify_filename(const char *prefix, const char *name);
412+
extern void verify_filename(const char *prefix,
413+
const char *name,
414+
int diagnose_misspelt_rev);
413415
extern void verify_non_filename(const char *prefix, const char *name);
414416

415417
#define INIT_DB_QUIET 0x0001

revision.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1781,7 +1781,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
17811781
* but the latter we have checked in the main loop.
17821782
*/
17831783
for (j = i; j < argc; j++)
1784-
verify_filename(revs->prefix, argv[j]);
1784+
verify_filename(revs->prefix, argv[j], j == i);
17851785

17861786
append_prune_data(&prune_data, argv + i);
17871787
break;

setup.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,17 @@ int check_filename(const char *prefix, const char *arg)
5353
die_errno("failed to stat '%s'", arg);
5454
}
5555

56-
static void NORETURN die_verify_filename(const char *prefix, const char *arg)
56+
static void NORETURN die_verify_filename(const char *prefix,
57+
const char *arg,
58+
int diagnose_misspelt_rev)
5759
{
5860
unsigned char sha1[20];
5961
unsigned mode;
6062

63+
if (!diagnose_misspelt_rev)
64+
die("%s: no such path in the working tree.\n"
65+
"Use '-- <path>...' to specify paths that do not exist locally.",
66+
arg);
6167
/*
6268
* Saying "'(icase)foo' does not exist in the index" when the
6369
* user gave us ":(icase)foo" is just stupid. A magic pathspec
@@ -80,14 +86,29 @@ static void NORETURN die_verify_filename(const char *prefix, const char *arg)
8086
* as true, because even if such a filename were to exist, we want
8187
* it to be preceded by the "--" marker (or we want the user to
8288
* use a format like "./-filename")
89+
*
90+
* The "diagnose_misspelt_rev" is used to provide a user-friendly
91+
* diagnosis when dying upon finding that "name" is not a pathname.
92+
* If set to 1, the diagnosis will try to diagnose "name" as an
93+
* invalid object name (e.g. HEAD:foo). If set to 0, the diagnosis
94+
* will only complain about an inexisting file.
95+
*
96+
* This function is typically called to check that a "file or rev"
97+
* argument is unambiguous. In this case, the caller will want
98+
* diagnose_misspelt_rev == 1 when verifying the first non-rev
99+
* argument (which could have been a revision), and
100+
* diagnose_misspelt_rev == 0 for the next ones (because we already
101+
* saw a filename, there's not ambiguity anymore).
83102
*/
84-
void verify_filename(const char *prefix, const char *arg)
103+
void verify_filename(const char *prefix,
104+
const char *arg,
105+
int diagnose_misspelt_rev)
85106
{
86107
if (*arg == '-')
87108
die("bad flag '%s' used after filename", arg);
88109
if (check_filename(prefix, arg))
89110
return;
90-
die_verify_filename(prefix, arg);
111+
die_verify_filename(prefix, arg, diagnose_misspelt_rev);
91112
}
92113

93114
/*

sha1_name.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1127,7 +1127,7 @@ int get_sha1_with_context_1(const char *name, unsigned char *sha1,
11271127
if (new_filename)
11281128
filename = new_filename;
11291129
ret = get_tree_entry(tree_sha1, filename, sha1, &oc->mode);
1130-
if (only_to_die) {
1130+
if (ret && only_to_die) {
11311131
diagnose_invalid_sha1_path(prefix, filename,
11321132
tree_sha1, object_name);
11331133
free(object_name);

t/t1506-rev-parse-diagnosis.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,15 @@ test_expect_success 'relative path when startup_info is NULL' '
171171
grep "BUG: startup_info struct is not initialized." error
172172
'
173173

174+
test_expect_success '<commit>:file correctly diagnosed after a pathname' '
175+
test_must_fail git rev-parse file.txt HEAD:file.txt 1>actual 2>error &&
176+
test_i18ngrep ! "exists on disk" error &&
177+
test_i18ngrep "no such path in the working tree" error &&
178+
cat >expect <<-\EOF &&
179+
file.txt
180+
HEAD:file.txt
181+
EOF
182+
test_cmp expect actual
183+
'
184+
174185
test_done

0 commit comments

Comments
 (0)