int matchlen = strlen(match);
const char *cp, *meta;
- if ((matchlen <= namelen) &&
- !strncmp(name, match, matchlen) &&
- (match[matchlen-1] == '/' ||
- name[matchlen] == '\0' || name[matchlen] == '/'))
+ if (!matchlen ||
+ ((matchlen <= namelen) &&
+ !strncmp(name, match, matchlen) &&
+ (match[matchlen-1] == '/' ||
+ name[matchlen] == '\0' || name[matchlen] == '/')))
return 1;
if (!fnmatch(match, name, 0))
return 1;
static int external_grep(struct grep_opt *opt, const char **paths, int cached)
{
- int i, nr, argc, hit, len;
+ int i, nr, argc, hit, len, status;
const char *argv[MAXARGS+1];
char randarg[ARGBUF];
char *argptr = randarg;
push_arg("-n");
if (opt->regflags & REG_EXTENDED)
push_arg("-E");
+ if (opt->regflags & REG_ICASE)
+ push_arg("-i");
if (opt->word_regexp)
push_arg("-w");
if (opt->name_only)
argv[argc++] = name;
if (argc < MAXARGS)
continue;
- hit += exec_grep(argc, argv);
+ status = exec_grep(argc, argv);
+ if (0 < status)
+ hit = 1;
argc = nr;
}
- if (argc > nr)
- hit += exec_grep(argc, argv);
- return 0;
+ if (argc > nr) {
+ status = exec_grep(argc, argv);
+ if (0 < status)
+ hit = 1;
+ }
+ return hit;
}
static int grep_cache(struct grep_opt *opt, const char **paths, int cached)
static int grep_object(struct grep_opt *opt, const char **paths,
struct object *obj, const char *name)
{
- if (!strcmp(obj->type, blob_type))
+ if (obj->type == TYPE_BLOB)
return grep_sha1(opt, obj->sha1, name);
- if (!strcmp(obj->type, commit_type) ||
- !strcmp(obj->type, tree_type)) {
+ if (obj->type == TYPE_COMMIT || obj->type == TYPE_TREE) {
struct tree_desc tree;
void *data;
int hit;
free(data);
return hit;
}
- die("unable to grep from object of type %s", obj->type);
+ die("unable to grep from object of type %s", typename(obj->type));
}
static const char builtin_grep_usage[] =
"git-grep <option>* <rev>* [-e] <pattern> [<path>...]";
+static const char emsg_invalid_context_len[] =
+"%s: invalid context length argument";
+static const char emsg_missing_context_len[] =
+"missing context length argument";
+static const char emsg_missing_argument[] =
+"option requires an argument -%s";
+
int cmd_grep(int argc, const char **argv, char **envp)
{
int hit = 0;
int cached = 0;
int seen_dashdash = 0;
struct grep_opt opt;
- struct object_list *list, **tail, *object_list = NULL;
+ struct object_array list = { 0, 0, NULL };
const char *prefix = setup_git_directory();
const char **paths = NULL;
int i;
* that continues up to the -- (if exists), and then paths.
*/
- tail = &object_list;
while (1 < argc) {
const char *arg = argv[1];
argc--; argv++;
case 'A': case 'B': case 'C':
if (!arg[2]) {
if (argc <= 1)
- usage(builtin_grep_usage);
+ die(emsg_missing_context_len);
scan = *++argv;
argc--;
}
break;
}
if (sscanf(scan, "%u", &num) != 1)
- usage(builtin_grep_usage);
+ die(emsg_invalid_context_len, scan);
switch (arg[1]) {
case 'A':
opt.post_context = num;
int lno = 0;
char buf[1024];
if (argc <= 1)
- usage(builtin_grep_usage);
+ die(emsg_missing_argument, arg);
patterns = fopen(argv[1], "r");
if (!patterns)
die("'%s': %s", argv[1], strerror(errno));
argc--;
continue;
}
- usage(builtin_grep_usage);
+ die(emsg_missing_argument, arg);
}
- if (!strcmp("--", arg))
+ if (!strcmp("--", arg)) {
+ /* later processing wants to have this at argv[1] */
+ argv--;
+ argc++;
break;
+ }
if (*arg == '-')
usage(builtin_grep_usage);
/* 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;
+ add_object_array(object, arg, &list);
continue;
}
if (!strcmp(arg, "--")) {
paths[1] = NULL;
}
- if (!object_list)
+ if (!list.nr)
return !grep_cache(&opt, paths, cached);
if (cached)
die("both --cached and trees are given.");
- for (list = object_list; list; list = list->next) {
+ for (i = 0; i < list.nr; i++) {
struct object *real_obj;
- real_obj = deref_tag(list->item, NULL, 0);
- if (grep_object(&opt, paths, real_obj, list->name))
+ real_obj = deref_tag(list.objects[i].item, NULL, 0);
+ if (grep_object(&opt, paths, real_obj, list.objects[i].name))
hit = 1;
}
return !hit;