if (!seen_dashdash) {
int j;
for (j = i; j < argc; j++)
- verify_filename(prefix, argv[j]);
+ verify_filename(prefix, argv[j], j == i);
}
paths = get_pathspec(prefix, argv + i);
rev = argv[i++];
} else {
/* Otherwise we treat this as a filename */
- verify_filename(prefix, argv[i]);
+ verify_filename(prefix, argv[i], 1);
}
}
if (as_is) {
if (show_file(arg) && as_is < 2)
- verify_filename(prefix, arg);
+ verify_filename(prefix, arg, 0);
continue;
}
if (!strcmp(arg,"-n")) {
as_is = 1;
if (!show_file(arg))
continue;
- verify_filename(prefix, arg);
+ verify_filename(prefix, arg, 1);
}
if (verify) {
if (revs_count == 1) {
extern char *prefix_path(const char *prefix, int len, const char *path);
extern const char *prefix_filename(const char *prefix, int len, const char *path);
extern int check_filename(const char *prefix, const char *name);
-extern void verify_filename(const char *prefix, const char *name);
+extern void verify_filename(const char *prefix,
+ const char *name,
+ int diagnose_misspelt_rev);
extern void verify_non_filename(const char *prefix, const char *name);
#define INIT_DB_QUIET 0x0001
* but the latter we have checked in the main loop.
*/
for (j = i; j < argc; j++)
- verify_filename(revs->prefix, argv[j]);
+ verify_filename(revs->prefix, argv[j], j == i);
append_prune_data(&prune_data, argv + i);
break;
die_errno("failed to stat '%s'", arg);
}
-static void NORETURN die_verify_filename(const char *prefix, const char *arg)
+static void NORETURN die_verify_filename(const char *prefix,
+ const char *arg,
+ int diagnose_misspelt_rev)
{
unsigned char sha1[20];
unsigned mode;
+ if (!diagnose_misspelt_rev)
+ die("%s: no such path in the working tree.\n"
+ "Use '-- <path>...' to specify paths that do not exist locally.",
+ arg);
/*
* Saying "'(icase)foo' does not exist in the index" when the
* user gave us ":(icase)foo" is just stupid. A magic pathspec
* as true, because even if such a filename were to exist, we want
* it to be preceded by the "--" marker (or we want the user to
* use a format like "./-filename")
+ *
+ * The "diagnose_misspelt_rev" is used to provide a user-friendly
+ * diagnosis when dying upon finding that "name" is not a pathname.
+ * If set to 1, the diagnosis will try to diagnose "name" as an
+ * invalid object name (e.g. HEAD:foo). If set to 0, the diagnosis
+ * will only complain about an inexisting file.
+ *
+ * This function is typically called to check that a "file or rev"
+ * argument is unambiguous. In this case, the caller will want
+ * diagnose_misspelt_rev == 1 when verifying the first non-rev
+ * argument (which could have been a revision), and
+ * diagnose_misspelt_rev == 0 for the next ones (because we already
+ * saw a filename, there's not ambiguity anymore).
*/
-void verify_filename(const char *prefix, const char *arg)
+void verify_filename(const char *prefix,
+ const char *arg,
+ int diagnose_misspelt_rev)
{
if (*arg == '-')
die("bad flag '%s' used after filename", arg);
if (check_filename(prefix, arg))
return;
- die_verify_filename(prefix, arg);
+ die_verify_filename(prefix, arg, diagnose_misspelt_rev);
}
/*
if (new_filename)
filename = new_filename;
ret = get_tree_entry(tree_sha1, filename, sha1, &oc->mode);
- if (only_to_die) {
+ if (ret && only_to_die) {
diagnose_invalid_sha1_path(prefix, filename,
tree_sha1, object_name);
free(object_name);
grep "BUG: startup_info struct is not initialized." error
'
+test_expect_success '<commit>:file correctly diagnosed after a pathname' '
+ test_must_fail git rev-parse file.txt HEAD:file.txt 1>actual 2>error &&
+ test_i18ngrep ! "exists on disk" error &&
+ test_i18ngrep "no such path in the working tree" error &&
+ cat >expect <<-\EOF &&
+ file.txt
+ HEAD:file.txt
+ EOF
+ test_cmp expect actual
+'
+
test_done