REDO . I made a hacked bash script with this script to do the paging (mentioned below), but noticed that your example is already a search path prefix. I changed your alias a bit and now find that this works for me:
[alias] gpx = "!f() { list=$1; shift; for r in . $list; do ( cd $r; git grep $@ | perl -pe \"s|^|$r/|\"; ); done ;}; f"
If you use a subshell, you can reset the functionality of "inr" (cd $ 1; cmd; ...) "(since it isolates chdir), and if you add". "then he will also look for a supermodule. I tested it with something like
git --no-pager gpx 'foo submodules/bar' --color=always -nIE '\w+\(\w*\)' | less -R
It seems to work well with escaping (was going to use git-rev-parse --sq-quote , but it looks like git is handling this for you already). This seems more elegant than the script elements listed below, and perhaps I could use your alias style with a function prefix and replace / simplify many of these functions. That said, thanks for showing it!
I tried to make another alias that gpx uses for the pager material, but it turned out to be a bit hairy with escaping, so I just made another alias:
[alias] gpxp = "!f() { list=$1; shift; for r in . $list; do ( cd $r; git --no-pager grep --color=always $@ | perl -pe \"s|^|$r/|\"; ); done | less -R ;}; f"
Then he becomes
git gpxp 'foo submodules/bar' -nIE '\w+\(\w*\)'
NOTE. If you get errors, they will appear in the grep text results.
ORIGINAL
I ran into similar problems with escaping and using git aliases.
I wrote a small extension to git-submodule that allows you to perform limited iteration. The help for this function is in git-submodule-ext foreach [-c | --constrain] git-submodule-ext foreach [-c | --constrain] ( help , implementation ). Installation instructions are here: README
If you want to limit the iteration to foo and something/bar , in your supermodule you can do
git config scm.focusGroup 'foo something/bar'
Then to execute your greppage
git --no-pager submodule-ext foreach -t -r -c -k git grep 'expression'
Or, if you install using aliases,
git --no-pager tsfer -c -k git grep 'expression'
The git --no-pager parameter is designed to prevent pulling up each submodule of $GIT_PAGER after each search. I added the --keep-going option to the script, so if grep returned nothing (the result is a non-zero state), it will not stop the iteration. Another solution is to make an example in the submodule documents using git tsfer -c -k 'git grep "expression" || :' git tsfer -c -k 'git grep "expression" || :' which work equivalently.
If your expression is complex, something like searching for function calls '\w+\(\w*\)' , you will need to enclose the entire expression in double quotes:
git --no-pager tsferp -c -k "git grep -E '\w+\(\w*\)'"
If escaping is a huge problem and you use bash, you export the function to use on iteration (script I extension using bash , not git standard /bin/sh )
greppage() { git grep -E 'some(really)?complex.*\(expression\)' } export -f greppage git --no-pager tsfer -c -k greppage
Hope this helps.
NOTE. The current drawback of this is that it can be difficult to determine which submodule matches, where the match is. A fix can be made somehow by adding the $name submodule, but I looked at git grep and couldn't find anything like it. I worked a little with the team and came up with this, well, "compact" command:
git --no-pager sube -q foreach -t -r -c -k "echo [ \$name ]'\n'; git grep --color=always -E '\w+\(\w*\)'; echo '\n\n'" | less -R
This makes the foreach silence quiet (suppresses "Enter" output) and adds some curly braces and newlines to make it easier to see divisions between submodules. Lemme see if I can make a function / alias for this to make it easier.
EDIT : a script is hacked here, which is not so elegant. I just made it a bash function to simplify things
git-greps() { git --no-pager sube -q foreach -t -r -c -k "git grep --color=always $(git rev-parse --sq-quote " $@ ") | perl -pe \"s|^|\$name/|\"" | less -R; }
Example
git-greps -nIE '\w+\(\w*\)'