On 17/10/10 03:28, Nguyen Thai Ngoc Duy wrote: > On Sat, Oct 16, 2010 at 6:26 AM, Chris Packham <judge.packham@xxxxxxxxx> wrote: >> +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? > The tree_name is a hangover from when I was passing it as a command line arg, I'll remove it. For now we still need to rewrite argv to modify the pathspec and max-depth, eventually I'd like to ditch that approach in favour of using fork() and modifying opts. >> + 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 > I was struggling a little with how to do this. The run_command invocation in submodules.c uses local_repo_env which is protected against modification. I also don't understand how the actual values are passed. If someone could point me in the right direction it'd be appreciated. >> + 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. > Originally I did set cp.dir but that is used by run_command (via start_command) to chdir. Which foils the cwd to worktree detection (at least in V1 of that patch). >> + 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 >> >> > > > -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html