git-grep: fix exit code when we use external grep.
[gitweb.git] / builtin-grep.c
index 5fac5701e6ccebdbe83b00d2e2df19343d3aea0e..bc53546dc713f425e1d35fd3716265a0bdf01702 100644 (file)
@@ -29,10 +29,11 @@ static int pathspec_matches(const char **paths, const char *name)
                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;
@@ -445,7 +446,7 @@ static int exec_grep(int argc, const char **argv)
 
 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;
@@ -535,12 +536,17 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
                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)
@@ -630,10 +636,9 @@ static int grep_tree(struct grep_opt *opt, const char **paths,
 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;
@@ -646,7 +651,7 @@ static int grep_object(struct grep_opt *opt, const char **paths,
                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[] =
@@ -658,7 +663,7 @@ int cmd_grep(int argc, const char **argv, char **envp)
        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;
@@ -678,7 +683,6 @@ int cmd_grep(int argc, const char **argv, char **envp)
         * that continues up to the -- (if exists), and then paths.
         */
 
-       tail = &object_list;
        while (1 < argc) {
                const char *arg = argv[1];
                argc--; argv++;
@@ -818,8 +822,12 @@ int cmd_grep(int argc, const char **argv, char **envp)
                        }
                        usage(builtin_grep_usage);
                }
-               if (!strcmp("--", arg))
+               if (!strcmp("--", arg)) {
+                       /* later processing wants to have this at argv[1] */
+                       argv--;
+                       argc++;
                        break;
+               }
                if (*arg == '-')
                        usage(builtin_grep_usage);
 
@@ -852,12 +860,9 @@ int cmd_grep(int argc, const char **argv, char **envp)
                /* 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, "--")) {
@@ -882,16 +887,16 @@ int cmd_grep(int argc, const char **argv, char **envp)
                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;