Merge branch 'bw/grep-recurse-submodules'
authorJunio C Hamano <gitster@pobox.com>
Tue, 28 Mar 2017 21:05:57 +0000 (14:05 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 28 Mar 2017 21:05:57 +0000 (14:05 -0700)
Build fix for NO_PTHREADS build.

* bw/grep-recurse-submodules:
grep: fix builds with with no thread support
grep: set default output method

1  2 
builtin/grep.c
diff --combined builtin/grep.c
index 837836fb3e3bf9cdeb25edf8789428aaf813f49d,33561f268d6ee580881d0e3e3b8db0da3f2c9b42..a9e82dc975e007fc2a77240ea1f9dca0803ecf32
@@@ -294,17 -294,17 +294,17 @@@ static int grep_cmd_config(const char *
        return st;
  }
  
 -static void *lock_and_read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size)
 +static void *lock_and_read_oid_file(const struct object_id *oid, enum object_type *type, unsigned long *size)
  {
        void *data;
  
        grep_read_lock();
 -      data = read_sha1_file(sha1, type, size);
 +      data = read_sha1_file(oid->hash, type, size);
        grep_read_unlock();
        return data;
  }
  
 -static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1,
 +static int grep_oid(struct grep_opt *opt, const struct object_id *oid,
                     const char *filename, int tree_name_len,
                     const char *path)
  {
  
  #ifndef NO_PTHREADS
        if (num_threads) {
 -              add_work(opt, GREP_SOURCE_SHA1, pathbuf.buf, path, sha1);
 +              add_work(opt, GREP_SOURCE_SHA1, pathbuf.buf, path, oid);
                strbuf_release(&pathbuf);
                return 0;
        } else
                struct grep_source gs;
                int hit;
  
 -              grep_source_init(&gs, GREP_SOURCE_SHA1, pathbuf.buf, path, sha1);
 +              grep_source_init(&gs, GREP_SOURCE_SHA1, pathbuf.buf, path, oid);
                strbuf_release(&pathbuf);
                hit = grep_source(opt, &gs);
  
@@@ -538,7 -538,7 +538,7 @@@ static int grep_submodule_launch(struc
        int status, i;
        const char *end_of_base;
        const char *name;
-       struct work_item *w = opt->output_priv;
+       struct strbuf child_output = STRBUF_INIT;
  
        end_of_base = strchr(gs->name, ':');
        if (gs->identifier && end_of_base)
         * child process.  A '0' indicates a hit, a '1' indicates no hit and
         * anything else is an error.
         */
-       status = capture_command(&cp, &w->out, 0);
+       status = capture_command(&cp, &child_output, 0);
        if (status && (status != 1)) {
                /* flush the buffer */
-               write_or_die(1, w->out.buf, w->out.len);
+               write_or_die(1, child_output.buf, child_output.len);
                die("process for submodule '%s' failed with exit code: %d",
                    gs->name, status);
        }
  
+       opt->output(opt, child_output.buf, child_output.len);
+       strbuf_release(&child_output);
        /* invert the return code to make a hit equal to 1 */
        return !status;
  }
@@@ -641,19 -643,14 +643,14 @@@ static int grep_submodule(struct grep_o
        } else
  #endif
        {
-               struct work_item w;
+               struct grep_source gs;
                int hit;
  
-               grep_source_init(&w.source, GREP_SOURCE_SUBMODULE,
+               grep_source_init(&gs, GREP_SOURCE_SUBMODULE,
                                 filename, path, sha1);
-               strbuf_init(&w.out, 0);
-               opt->output_priv = &w;
-               hit = grep_submodule_launch(opt, &w.source);
+               hit = grep_submodule_launch(opt, &gs);
  
-               write_or_die(1, w.out.buf, w.out.len);
-               grep_source_clear(&w.source);
-               strbuf_release(&w.out);
+               grep_source_clear(&gs);
                return hit;
        }
  }
@@@ -690,7 -687,7 +687,7 @@@ static int grep_cache(struct grep_opt *
                            ce_skip_worktree(ce)) {
                                if (ce_stage(ce) || ce_intent_to_add(ce))
                                        continue;
 -                              hit |= grep_sha1(opt, ce->oid.hash, ce->name,
 +                              hit |= grep_oid(opt, &ce->oid, ce->name,
                                                 0, ce->name);
                        } else {
                                hit |= grep_file(opt, ce->name);
@@@ -750,7 -747,7 +747,7 @@@ static int grep_tree(struct grep_opt *o
                strbuf_add(base, entry.path, te_len);
  
                if (S_ISREG(entry.mode)) {
 -                      hit |= grep_sha1(opt, entry.oid->hash, base->buf, tn_len,
 +                      hit |= grep_oid(opt, entry.oid, base->buf, tn_len,
                                         check_attr ? base->buf + tn_len : NULL);
                } else if (S_ISDIR(entry.mode)) {
                        enum object_type type;
                        void *data;
                        unsigned long size;
  
 -                      data = lock_and_read_sha1_file(entry.oid->hash, &type, &size);
 +                      data = lock_and_read_oid_file(entry.oid, &type, &size);
                        if (!data)
                                die(_("unable to read tree (%s)"),
                                    oid_to_hex(entry.oid));
@@@ -787,7 -784,7 +784,7 @@@ static int grep_object(struct grep_opt 
                       struct object *obj, const char *name, const char *path)
  {
        if (obj->type == OBJ_BLOB)
 -              return grep_sha1(opt, obj->oid.hash, name, 0, path);
 +              return grep_oid(opt, &obj->oid, name, 0, path);
        if (obj->type == OBJ_COMMIT || obj->type == OBJ_TREE) {
                struct tree_desc tree;
                void *data;
@@@ -967,7 -964,6 +964,7 @@@ int cmd_grep(int argc, const char **arg
        int dummy;
        int use_index = 1;
        int pattern_type_arg = GREP_PATTERN_TYPE_UNSPECIFIED;
 +      int allow_revs;
  
        struct option options[] = {
                OPT_BOOL(0, "cached", &cached,
  
        compile_grep_patterns(&opt);
  
 -      /* Check revs and then paths */
 +      /*
 +       * We have to find "--" in a separate pass, because its presence
 +       * influences how we will parse arguments that come before it.
 +       */
 +      for (i = 0; i < argc; i++) {
 +              if (!strcmp(argv[i], "--")) {
 +                      seen_dashdash = 1;
 +                      break;
 +              }
 +      }
 +
 +      /*
 +       * Resolve any rev arguments. If we have a dashdash, then everything up
 +       * to it must resolve as a rev. If not, then we stop at the first
 +       * non-rev and assume everything else is a path.
 +       */
 +      allow_revs = use_index && !untracked;
        for (i = 0; i < argc; i++) {
                const char *arg = argv[i];
 -              unsigned char sha1[20];
 +              struct object_id oid;
                struct object_context oc;
 -              /* Is it a rev? */
 -              if (!get_sha1_with_context(arg, 0, sha1, &oc)) {
 -                      struct object *object = parse_object_or_die(sha1, arg);
 -                      if (!seen_dashdash)
 -                              verify_non_filename(prefix, arg);
 -                      add_object_array_with_path(object, arg, &list, oc.mode, oc.path);
 -                      continue;
 -              }
 +              struct object *object;
 +
                if (!strcmp(arg, "--")) {
                        i++;
 -                      seen_dashdash = 1;
 +                      break;
                }
 -              break;
 +
 +              if (!allow_revs) {
 +                      if (seen_dashdash)
 +                              die(_("--no-index or --untracked cannot be used with revs"));
 +                      break;
 +              }
 +
 +              if (get_sha1_with_context(arg, 0, oid.hash, &oc)) {
 +                      if (seen_dashdash)
 +                              die(_("unable to resolve revision: %s"), arg);
 +                      break;
 +              }
 +
 +              object = parse_object_or_die(oid.hash, arg);
 +              if (!seen_dashdash)
 +                      verify_non_filename(prefix, arg);
 +              add_object_array_with_path(object, arg, &list, oc.mode, oc.path);
        }
  
 +      /*
 +       * Anything left over is presumed to be a path. But in the non-dashdash
 +       * "do what I mean" case, we verify and complain when that isn't true.
 +       */
 +      if (!seen_dashdash) {
 +              int j;
 +              for (j = i; j < argc; j++)
 +                      verify_filename(prefix, argv[j], j == i && allow_revs);
 +      }
 +
 +      parse_pathspec(&pathspec, 0,
 +                     PATHSPEC_PREFER_CWD |
 +                     (opt.max_depth != -1 ? PATHSPEC_MAXDEPTH_VALID : 0),
 +                     prefix, argv + i);
 +      pathspec.max_depth = opt.max_depth;
 +      pathspec.recursive = 1;
 +
  #ifndef NO_PTHREADS
        if (list.nr || cached || show_in_pager)
                num_threads = 0;
        }
  #endif
  
 -      /* The rest are paths */
 -      if (!seen_dashdash) {
 -              int j;
 -              for (j = i; j < argc; j++)
 -                      verify_filename(prefix, argv[j], j == i);
 -      }
 -
 -      parse_pathspec(&pathspec, 0,
 -                     PATHSPEC_PREFER_CWD |
 -                     (opt.max_depth != -1 ? PATHSPEC_MAXDEPTH_VALID : 0),
 -                     prefix, argv + i);
 -      pathspec.max_depth = opt.max_depth;
 -      pathspec.recursive = 1;
 -
        if (recurse_submodules) {
                gitmodules_config();
                compile_submodule_options(&opt, &pathspec, cached, untracked,
  
        if (!use_index || untracked) {
                int use_exclude = (opt_exclude < 0) ? use_index : !!opt_exclude;
 -              if (list.nr)
 -                      die(_("--no-index or --untracked cannot be used with revs."));
                hit = grep_directory(&opt, &pathspec, use_exclude, use_index);
        } else if (0 <= opt_exclude) {
                die(_("--[no-]exclude-standard cannot be used for tracked contents."));