How to git grep the main repository and all its submodules?
With Git 2.12 (Q1 2017), you won't need any git submodule foreach
trick.
Simply:
git grep -e "bar" --recurse-submodules
See commit e6fac7f, commit 74ed437, commit 0281e48, commit 4538eef, commit 9ebf689, commit f9f4256, commit 5688c28 (16 Dec 2016), and commit 4ac9006, commit 7241764, commit a1ae484, commit 05b458c (12 Dec 2016) by Brandon Williams (mbrandonw
).
See commit e9a379c (21 Dec 2016) by Johannes Sixt (j6t
).
(Merged by Junio C Hamano -- gitster
-- in commit 55d128a, 18 Jan 2017)
grep
: optionally recurse into submodulesAllow
grep
to recognize submodules and recursively search for patterns in each submodule.
This is done by forking off a process to recursively call grep on each submodule.Recursion only occurs for submodules which have been initialized and checked out by the parent project. If a submodule hasn't been initialized and checked out it is simply skipped.
In order to support the existing multi-threading infrastructure in
grep
, output from each child process is captured in a strbuf so that it can be later printed to the console in an ordered fashion.To limit the number of theads that are created, each child process has half the number of threads as its parents (minimum of 1), otherwise we potentially have a fork-bomb.
The git grep
man page now includes:
--recurse-submodules
Recursively search in each submodule that has been initialized and checked out in the repository.
When used in combination with the<tree>
option the prefix of all submodule output will be the name of the parent project's<tree>
object.
With Git 2.14.x/2.15 (Q3 2017), "git grep --recurse-submodules
" has been reworked to give a more consistent output across submodule boundary (and do its thing without having to fork a separate process).
See commit f9ee2fc, commit 2184d4b, commit 34e2ba0, commit 91b8348, commit 8fa2915, commit f20e7c1, commit b22e51c, commit 4c0eeaf (02 Aug 2017), and commit ba43964, commit 3f13877 (18 Jul 2017) by Brandon Williams (mbrandonw
).
(Merged by Junio C Hamano -- gitster
-- in commit 5aa0b6c, 22 Aug 2017)
That means the internal --parent-basename <basename>
option of git grep
does no longer exists.
Make sure to use Git 2.21 (Q1 2019), as a bug has been fixed regarding cywin paths: see "Cygwin uses relative and absolute path for environment variables".
Actually, before Git 2.23.1/2.24 (Q4 2019), "git grep --recurse-submodules
" that looks at the working tree files looked at the contents in the index in submodules, instead of files in the working tree.
That has been fixed.
See commit 6a289d4 (30 Jul 2019) by Matheus Tavares (matheustavares
).
(Merged by Junio C Hamano -- gitster
-- in commit 3071797, 22 Aug 2019)
grep
: fix worktree case in submodulesRunning
git-grep
with--recurse-submodules
results in a cachedgrep
for the submodules even when--cached
is not used.
This makes all modifications in submodules' tracked files be always ignored when grepping.Solve that making
git grep
respect the cached option when invokinggrep_cache()
insidegrep_submodule()
.
Also, add tests to ensure that the desired behavior is performed.
"git grep --no-index
" should not get affected by the contents of the .gitmodules
file but when "--recurse-submodules
" is given or the "submodule.recurse
" variable is set, it did.
No more, with Git 2.25.1 (Feb. 2020).
Now these settings are ignored in the "--no-index
" mode.
See commit c56c48d (30 Jan 2020) by Philippe Blain (phil-blain
).
(Merged by Junio C Hamano -- gitster
-- in commit 556ccd4, 12 Feb 2020)
See discussion.
grep
: ignore--recurse-submodules
if--no-index
is givenHelped-by: Junio C Hamano
Signed-off-by: Philippe BlainSince grep learned to recurse into submodules in 0281e487fd ("
grep
: optionally recurse into submodules", 2016-12-16, Git v2.12.0-rc0 -- merge listed in batch #6), using--recurse-submodules
along with--no-index
makes Gitdie()
.This is unfortunate because if
submodule.recurse
is set in a user's~/.gitconfig
, invokinggit grep --no-index
either inside or outside a Git repository results in:fatal: option not supported with --recurse-submodules
Let's allow using these options together, so that setting submodule.recurse globally does not prevent using
git grep --no-index
.Using
--recurse-submodules
should not have any effect if--no-index
is used inside a repository, as Git will recurse into the checked out submodule directories just like into regular directories.
Generally, similar to "GitConfig: bad config for shell command", it may be because the '\
' character is interpreted by git first, before being executed in a shell.
But in your case, this should work as expected because of the surrounding double-quotes.
It does work on my git 1.8.4 on Ubuntu.
So simplify your .gitconfig
and check if works better if it contains your alias (and nothing) else.
If that does work, then the issue is elsewhere in your config file.