summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 1c57119)
raw | patch | inline | side by side (parent: 1c57119)
author | Junio C Hamano <junkio@cox.net> | |
Tue, 9 May 2006 06:55:47 +0000 (23:55 -0700) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Tue, 9 May 2006 06:55:47 +0000 (23:55 -0700) |
I mistyped
git grep next -e '"^@"' '*.c'
and got many hits that contain "next" without complaint.
Obviously what I meant to say was:
git grep -e '"^@"' next -- '*.c'
This tightens the argument parsing rule a bit:
- All "grep" parameters should come first;
- If there is no -e nor -f to specify pattern, the first non
option string is the parameter;
- After that, zero or more revs can follow.
- An optional '--' can be present, and is skipped.
- All the rest are pathspecs. If '--' was not there, they must
be paths that exist in the working tree.
Signed-off-by: Junio C Hamano <junkio@cox.net>
git grep next -e '"^@"' '*.c'
and got many hits that contain "next" without complaint.
Obviously what I meant to say was:
git grep -e '"^@"' next -- '*.c'
This tightens the argument parsing rule a bit:
- All "grep" parameters should come first;
- If there is no -e nor -f to specify pattern, the first non
option string is the parameter;
- After that, zero or more revs can follow.
- An optional '--' can be present, and is skipped.
- All the rest are pathspecs. If '--' was not there, they must
be paths that exist in the working tree.
Signed-off-by: Junio C Hamano <junkio@cox.net>
builtin-grep.c | patch | blob | history |
diff --git a/builtin-grep.c b/builtin-grep.c
index a762c48a5a3de70c47814df830aae0760549d163..26a3fc387ff0def55ce29494840b4e3437f6bbc2 100644 (file)
--- a/builtin-grep.c
+++ b/builtin-grep.c
int cmd_grep(int argc, const char **argv, char **envp)
{
int hit = 0;
- int no_more_flags = 0;
int cached = 0;
+ int seen_dashdash = 0;
struct grep_opt opt;
struct object_list *list, **tail, *object_list = NULL;
const char *prefix = setup_git_directory();
const char **paths = NULL;
+ int i;
memset(&opt, 0, sizeof(opt));
opt.pattern_tail = &opt.pattern_list;
opt.regflags = REG_NEWLINE;
/*
- * No point using rev_info, really.
+ * If there is no -- then the paths must exist in the working
+ * tree. If there is no explicit pattern specified with -e or
+ * -f, we take the first unrecognized non option to be the
+ * pattern, but then what follows it must be zero or more
+ * valid refs up to the -- (if exists), and then existing
+ * paths. If there is an explicit pattern, then the first
+ * unrecocnized non option is the beginning of the refs list
+ * that continues up to the -- (if exists), and then paths.
*/
+
+ tail = &object_list;
while (1 < argc) {
const char *arg = argv[1];
argc--; argv++;
usage(builtin_grep_usage);
patterns = fopen(argv[1], "r");
if (!patterns)
- die("'%s': %s", strerror(errno));
+ die("'%s': %s", argv[1], strerror(errno));
while (fgets(buf, sizeof(buf), patterns)) {
int len = strlen(buf);
if (buf[len-1] == '\n')
}
usage(builtin_grep_usage);
}
- if (!strcmp("--", arg)) {
- no_more_flags = 1;
- continue;
- }
- /* Either unrecognized option or a single pattern */
- if (!no_more_flags && *arg == '-')
+ if (!strcmp("--", arg))
+ break;
+ if (*arg == '-')
usage(builtin_grep_usage);
+
+ /* First unrecognized non-option token */
if (!opt.pattern_list) {
add_pattern(&opt, arg, "command line", 0);
break;
}
else {
/* We are looking at the first path or rev;
- * it is found at argv[0] after leaving the
+ * it is found at argv[1] after leaving the
* loop.
*/
argc++; argv--;
break;
}
}
+
if (!opt.pattern_list)
die("no pattern given.");
compile_patterns(&opt);
- tail = &object_list;
- while (1 < argc) {
- struct object *object;
- struct object_list *elem;
- const char *arg = argv[1];
+
+ /* Check revs and then paths */
+ for (i = 1; i < argc; i++) {
+ const char *arg = argv[i];
unsigned char sha1[20];
- if (get_sha1(arg, sha1) < 0)
- break;
- object = parse_object(sha1);
- if (!object)
- die("bad object %s", arg);
- elem = object_list_insert(object, tail);
- elem->name = arg;
- tail = &elem->next;
- argc--; argv++;
+ /* Is it a rev? */
+ if (!get_sha1(arg, sha1)) {
+ struct object *object = parse_object(sha1);
+ struct object_list *elem;
+ if (!object)
+ die("bad object %s", arg);
+ elem = object_list_insert(object, tail);
+ elem->name = arg;
+ tail = &elem->next;
+ continue;
+ }
+ if (!strcmp(arg, "--")) {
+ i++;
+ seen_dashdash = 1;
+ }
+ break;
}
- if (1 < argc)
- paths = get_pathspec(prefix, argv + 1);
+
+ /* The rest are paths */
+ if (!seen_dashdash) {
+ int j;
+ for (j = i; j < argc; i++)
+ verify_filename(prefix, argv[j]);
+ }
+
+ if (i < argc)
+ paths = get_pathspec(prefix, argv + i);
else if (prefix) {
paths = xcalloc(2, sizeof(const char *));
paths[0] = prefix;