Brandon Williams <bmwill@xxxxxxxxxx> writes: > +static void compile_submodule_options(const struct grep_opt *opt, > + const struct pathspec *pathspec, > + int cached, int untracked, > + int opt_exclude, int use_index, > + int pattern_type_arg) > +{ > + struct grep_pat *pattern; > + int i; > + > + if (recurse_submodules) > + argv_array_push(&submodule_options, "--recurse-submodules"); > + > + if (cached) > + argv_array_push(&submodule_options, "--cached"); > +... > + > + /* Add Pathspecs */ > + argv_array_push(&submodule_options, "--"); > + for (i = 0; i < pathspec->nr; i++) > + argv_array_push(&submodule_options, > + pathspec->items[i].original); > +} When I do $ git grep --recurse-submodules pattern submodules/ lib/ where I have bunch of submodules in "submodules/" directory in the top-level project, the top-level grep would try to find the pattern in its own files in its "lib/" directory and then invoke sub-greps in the submodule/a, submodule/b, etc. working trees. This passes the "submodules/" and "lib/" pathspec down to these sub-greps. These sub-greps in turn learn via --super-prefix where they are in the super-project's context (e.g. "submodules/a/") to adjust the given pathspec patterns, so everything cancels out (e.g. they know "lib/" is totally outside of their area and their files do not match with the pathspec element "lib/" at all). Looking good.