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? > +    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. > +    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 ÿô.nÇ·®+%˱é¥wÿº{.nÇ· ßØnr¡öë¨è&£ûz¹Þúzf£¢·h§~Ûÿÿïÿê_èæ+v¨þ)ßø