check-ignore: allow incremental streaming of queries via --stdin
[gitweb.git] / builtin / check-ignore.c
index 59acf74c58cff87842734664050204ff6130447b..c00a7d6bb9d239e2b0fef97c8157d109c6073bfd 100644 (file)
@@ -63,30 +63,20 @@ static void output_exclude(const char *path, struct exclude *exclude)
        }
 }
 
-static int check_ignore(const char *prefix, const char **pathspec)
+static int check_ignore(struct path_exclude_check *check,
+                       const char *prefix, const char **pathspec)
 {
-       struct dir_struct dir;
        const char *path, *full_path;
        char *seen;
        int num_ignored = 0, dtype = DT_UNKNOWN, i;
-       struct path_exclude_check check;
        struct exclude *exclude;
 
-       /* read_cache() is only necessary so we can watch out for submodules. */
-       if (read_cache() < 0)
-               die(_("index file corrupt"));
-
-       memset(&dir, 0, sizeof(dir));
-       dir.flags |= DIR_COLLECT_IGNORED;
-       setup_standard_excludes(&dir);
-
        if (!pathspec || !*pathspec) {
                if (!quiet)
                        fprintf(stderr, "no pathspec given.\n");
                return 0;
        }
 
-       path_exclude_check_init(&check, &dir);
        /*
         * look for pathspecs matching entries in the index, since these
         * should not be ignored, in order to be consistent with
@@ -101,7 +91,7 @@ static int check_ignore(const char *prefix, const char **pathspec)
                die_if_path_beyond_symlink(full_path, prefix);
                exclude = NULL;
                if (!seen[i]) {
-                       exclude = last_exclude_matching_path(&check, full_path,
+                       exclude = last_exclude_matching_path(check, full_path,
                                                             -1, &dtype);
                }
                if (!quiet && (exclude || show_non_matching))
@@ -110,19 +100,16 @@ static int check_ignore(const char *prefix, const char **pathspec)
                        num_ignored++;
        }
        free(seen);
-       clear_directory(&dir);
-       path_exclude_check_clear(&check);
 
        return num_ignored;
 }
 
-static int check_ignore_stdin_paths(const char *prefix)
+static int check_ignore_stdin_paths(struct path_exclude_check *check, const char *prefix)
 {
        struct strbuf buf, nbuf;
-       char **pathspec = NULL;
-       size_t nr = 0, alloc = 0;
+       char *pathspec[2] = { NULL, NULL };
        int line_termination = null_term_line ? 0 : '\n';
-       int num_ignored;
+       int num_ignored = 0;
 
        strbuf_init(&buf, 0);
        strbuf_init(&nbuf, 0);
@@ -133,23 +120,20 @@ static int check_ignore_stdin_paths(const char *prefix)
                                die("line is badly quoted");
                        strbuf_swap(&buf, &nbuf);
                }
-               ALLOC_GROW(pathspec, nr + 1, alloc);
-               pathspec[nr] = xcalloc(strlen(buf.buf) + 1, sizeof(*buf.buf));
-               strcpy(pathspec[nr++], buf.buf);
+               pathspec[0] = buf.buf;
+               num_ignored += check_ignore(check, prefix, (const char **)pathspec);
+               maybe_flush_or_die(stdout, "check-ignore to stdout");
        }
-       ALLOC_GROW(pathspec, nr + 1, alloc);
-       pathspec[nr] = NULL;
-       num_ignored = check_ignore(prefix, (const char **)pathspec);
-       maybe_flush_or_die(stdout, "attribute to stdout");
        strbuf_release(&buf);
        strbuf_release(&nbuf);
-       free(pathspec);
        return num_ignored;
 }
 
 int cmd_check_ignore(int argc, const char **argv, const char *prefix)
 {
        int num_ignored;
+       struct dir_struct dir;
+       struct path_exclude_check check;
 
        git_config(git_default_config, NULL);
 
@@ -174,12 +158,24 @@ int cmd_check_ignore(int argc, const char **argv, const char *prefix)
        if (show_non_matching && !verbose)
                die(_("--non-matching is only valid with --verbose"));
 
+       /* read_cache() is only necessary so we can watch out for submodules. */
+       if (read_cache() < 0)
+               die(_("index file corrupt"));
+
+       memset(&dir, 0, sizeof(dir));
+       dir.flags |= DIR_COLLECT_IGNORED;
+       setup_standard_excludes(&dir);
+
+       path_exclude_check_init(&check, &dir);
        if (stdin_paths) {
-               num_ignored = check_ignore_stdin_paths(prefix);
+               num_ignored = check_ignore_stdin_paths(&check, prefix);
        } else {
-               num_ignored = check_ignore(prefix, argv);
+               num_ignored = check_ignore(&check, prefix, argv);
                maybe_flush_or_die(stdout, "ignore to stdout");
        }
 
+       clear_directory(&dir);
+       path_exclude_check_clear(&check);
+
        return !num_ignored;
 }