Re: [RFC/PATCHv2 5/5] grep: add support for grepping in submodules
- From
Nguyen Thai Ngoc Duy <pclouds@gmail.com>
- Date
- Oct 17, 2010, 10:28 UTC
- Message-ID
- <AANLkTikSukNCkcx4RYRuzzKU8T64mT0boMDqoNBrWW73@mail.gmail.com>
- In-Reply-To
- <1287185204-843-6-git-send-email-judge.packham@gmail.com>
On Sat, Oct 16, 2010 at 6:26 AM, Chris Packham <judge.packham@gmail.com> wrote:
Show 7 quoted lines
> +static int grep_submodule(struct grep_opt *opt, const char *path,
> + const char *sha1, const char *tree_name)
> +{
> + struct strbuf buf = STRBUF_INIT;
> + struct strbuf pre_buf = STRBUF_INIT;
> + struct child_process cp;
> + const char **argv = create_sub_grep_argv(opt, path, sha1, tree_name);Can we just save sha1 in a env variable and drop this argv rewrite?
Show 14 quoted lines
> + const char *git_dir;
> + int hit = 0;
> + memset(&cp, 0, sizeof(cp));
> +
> + strbuf_addf(&buf, "%s/.git", path);
> + git_dir = read_gitfile_gently(buf.buf);
> + if (!git_dir)
> + git_dir = buf.buf;
> + if (!is_directory(git_dir))
> + goto out_free;
> +
> + setenv("GIT_SUPER_REFNAME", tree_name, 1);
> + setenv(GIT_DIR_ENVIRONMENT, git_dir, 1);
> + setenv(GIT_WORK_TREE_ENVIRONMENT, path, 1);cp.env can be used to set these variables
> + cp.argv = argv; > + cp.git_cmd = 1; > + cp.no_stdin = 1;
I think you stll need "cp.dir = path;" here because the setup routines won't do that for you. But I need to check/test that.
Show 80 quoted lines
> + if (run_command(&cp) == 0)
> + hit = 1;
> +out_free:
> + unsetenv("GIT_SUPER_REFNAME");
> + unsetenv(GIT_DIR_ENVIRONMENT);
> + unsetenv(GIT_WORK_TREE_ENVIRONMENT);
> + free(argv);
> + strbuf_release(&buf);
> + strbuf_release(&pre_buf);
> + return hit;
> +}
> +
> static int grep_cache(struct grep_opt *opt, const char **paths, int cached)
> {
> int hit = 0;
> @@ -597,6 +682,10 @@ static int grep_cache(struct grep_opt *opt, const char **paths, int cached)
> struct cache_entry *ce = active_cache[nr];
> if (!pathspec_matches(paths, ce->name, opt->max_depth))
> continue;
> + if (S_ISGITLINK(ce->ce_mode) && opt->recurse_submodules) {
> + hit |= grep_submodule(opt, ce->name, NULL, NULL);
> + continue;
> + }
> if (!S_ISREG(ce->ce_mode))
> continue;
> /*
> @@ -634,11 +723,16 @@ static int grep_tree(struct grep_opt *opt, const char **paths,
> char *down;
> int tn_len = strlen(tree_name);
> struct strbuf pathbuf;
> + const char *refname = getenv("GIT_SUPER_REFNAME");
> + int rn_len = refname ? strlen(refname) : 0;
>
> - strbuf_init(&pathbuf, PATH_MAX + tn_len);
> + strbuf_init(&pathbuf, PATH_MAX + MAX(tn_len, rn_len));
>
> if (tn_len) {
> - strbuf_add(&pathbuf, tree_name, tn_len);
> + if (refname)
> + strbuf_add(&pathbuf, refname, rn_len);
> + else
> + strbuf_add(&pathbuf, tree_name, tn_len);
> strbuf_addch(&pathbuf, ':');
> tn_len = pathbuf.len;
> }
> @@ -664,6 +758,9 @@ static int grep_tree(struct grep_opt *opt, const char **paths,
> ;
> else if (S_ISREG(entry.mode))
> hit |= grep_sha1(opt, entry.sha1, pathbuf.buf, tn_len);
> + else if (S_ISGITLINK(entry.mode) && opt->recurse_submodules)
> + hit |= grep_submodule(opt, entry.path,
> + sha1_to_hex(entry.sha1), tree_name);
> else if (S_ISDIR(entry.mode)) {
> enum object_type type;
> struct tree_desc sub;
> @@ -931,6 +1028,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
> "allow calling of grep(1) (ignored by this build)"),
> { OPTION_CALLBACK, 0, "help-all", &options, NULL, "show usage",
> PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, help_callback },
> + OPT_BOOLEAN(0, "recursive", &opt.recurse_submodules,
> + "recurse into submodules"),
> OPT_END()
> };
>
> diff --git a/grep.h b/grep.h
> index 06621fe..d5e2e11 100644
> --- a/grep.h
> +++ b/grep.h
> @@ -101,6 +101,7 @@ struct grep_opt {
> unsigned post_context;
> unsigned last_shown;
> int show_hunk_mark;
> + int recurse_submodules;
> void *priv;
>
> void (*output)(struct grep_opt *opt, const void *data, size_t size);
> --
> 1.7.3.1
>
>-- Duy