revision parsing: make "rev -- paths" checks stronger.
If you don't have a "--" marker, then: - all of the arguments we are going to assume are pathspecs must exist in the working tree. - none of the arguments we parsed as revisions could be interpreted as a filename. so that there really isn't any possibility of confusion in case somebody does have a revision that looks like a pathname too. The former rule has been in effect; this implements the latter. Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
69bcc43eca
commit
ea92f41ff9
1
cache.h
1
cache.h
@ -135,6 +135,7 @@ extern const char *setup_git_directory(void);
|
||||
extern const 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 void verify_filename(const char *prefix, const char *name);
|
||||
extern void verify_non_filename(const char *prefix, const char *name);
|
||||
|
||||
#define alloc_nr(x) (((x)+16)*3/2)
|
||||
|
||||
|
14
revision.c
14
revision.c
@ -740,6 +740,11 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
||||
include = get_reference(revs, next, sha1, flags);
|
||||
if (!exclude || !include)
|
||||
die("Invalid revision range %s..%s", arg, next);
|
||||
|
||||
if (!seen_dashdash) {
|
||||
*dotdot = '.';
|
||||
verify_non_filename(revs->prefix, arg);
|
||||
}
|
||||
add_pending_object(revs, exclude, this);
|
||||
add_pending_object(revs, include, next);
|
||||
continue;
|
||||
@ -757,13 +762,20 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
||||
if (seen_dashdash || local_flags)
|
||||
die("bad revision '%s'", arg);
|
||||
|
||||
/* If we didn't have a "--", all filenames must exist */
|
||||
/* If we didn't have a "--":
|
||||
* (1) all filenames must exist;
|
||||
* (2) all rev-args must not be interpretable
|
||||
* as a valid filename.
|
||||
* but the latter we have checked in the main loop.
|
||||
*/
|
||||
for (j = i; j < argc; j++)
|
||||
verify_filename(revs->prefix, argv[j]);
|
||||
|
||||
revs->prune_data = get_pathspec(revs->prefix, argv + i);
|
||||
break;
|
||||
}
|
||||
if (!seen_dashdash)
|
||||
verify_non_filename(revs->prefix, arg);
|
||||
object = get_reference(revs, arg, sha1, flags ^ local_flags);
|
||||
add_pending_object(revs, object, arg);
|
||||
}
|
||||
|
22
setup.c
22
setup.c
@ -80,8 +80,28 @@ void verify_filename(const char *prefix, const char *arg)
|
||||
if (!lstat(name, &st))
|
||||
return;
|
||||
if (errno == ENOENT)
|
||||
die("ambiguous argument '%s': unknown revision or filename\n"
|
||||
die("ambiguous argument '%s': unknown revision or path not in the working tree.\n"
|
||||
"Use '--' to separate paths from revisions", arg);
|
||||
die("'%s': %s", arg, strerror(errno));
|
||||
}
|
||||
|
||||
/*
|
||||
* Opposite of the above: the command line did not have -- marker
|
||||
* and we parsed the arg as a refname. It should not be interpretable
|
||||
* as a filename.
|
||||
*/
|
||||
void verify_non_filename(const char *prefix, const char *arg)
|
||||
{
|
||||
const char *name;
|
||||
struct stat st;
|
||||
|
||||
if (*arg == '-')
|
||||
return; /* flag */
|
||||
name = prefix ? prefix_filename(prefix, strlen(prefix), arg) : arg;
|
||||
if (!lstat(name, &st))
|
||||
die("ambiguous argument '%s': both revision and filename\n"
|
||||
"Use '--' to separate filenames from revisions", arg);
|
||||
if (errno != ENOENT)
|
||||
die("'%s': %s", arg, strerror(errno));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user