Reputation: 11609
Is it possible to run git grep
inside all the branches of a Git control sourced project? Or is there another command to run?
Upvotes: 194
Views: 95136
Reputation: 688
What about git branch | grep "[item to be searched]"
.
This will search all branch names for the one you can pattern match on the string.
This will not search the contents of each file in that branch.
Upvotes: -2
Reputation: 1323793
The question "How to grep (search) committed code in the Git history?" recommends:
git grep <regexp> $(git rev-list --all)
That searches through all the commits, which should include all the branches.
Another form would be:
git rev-list --all | (
while read revision; do
git grep -F 'yourWord' $revision
done
)
You can find even more example in this article:
I tried the above on one project large enough that git complained about the argument size, so if you run into this problem, do something like:
git rev-list --all | (while read rev; do git grep -e <regexp> $rev; done)
(see an alternative in the last section of this answer, below)
Don't forget those settings, if you want them:
# Allow Extended Regular Expressions
git config --global grep.extendedRegexp true
# Always Include Line Numbers
git config --global grep.lineNumber true
This alias can help too:
git config --global alias.g "grep --break --heading --line-number"
Update August 2016: R.M. recommends in the comments
I got a "
fatal: bad flag '->' used after filename
" when trying thegit branch
version. The error was associated with aHEAD
aliasing notation.I solved it by adding a
sed '/->/d'
in the pipe, between thetr
and thexargs
commands.git branch -a | tr -d \* | sed '/->/d' | xargs git grep <regexp>
That is:
alias grep_all="git branch -a | tr -d \* | sed '/->/d' | xargs git grep"
grep_all <regexp>
This is an improvement over the solution chernjie had suggested, since git rev-list --all
is an overkill.
A more refined command can be:
# Don't use this, see above git branch -a | tr -d \* | xargs git grep <regexp>
Which will allow you to search only branches (including remote branches)
You can even create a bash/zsh alias for it:
# Don't use this, see above alias grep_all="git branch -a | tr -d \* | xargs git grep" grep_all <regexp>
Jan. 2024: Gabriel Staples adds in the comments:
For anyone who wants to search just the tip commits on every branch in the repo, rather than every commit in the repo, and if you'd like to do parallel processes to speed up the search, see my very extensive answer here:
All about searching (via
grep
or similar) in your git repositories.
I build upon some of the content in this answer.
Upvotes: 243
Reputation: 111
It's possible to do it in two common ways: Bash or Git aliases
Here are three commands:
git grep-branch
- Search in all branches local & remotegit grep-branch-local
- Search in local branches onlygit grep-branch-remote
- Remote branches onlyUsage is the same as git grep
:
git grep-branch "find my text"
git grep-branch --some-grep-options "find my text"
~/.gitconfig
Commands should be added manually to ~/.gitconfig
file, because git config --global alias
evaluate complex code you add and mess it up.
[alias]
grep-branch = "!f(){ git branch -a | sed -e 's/[ \\*]*//' | grep -v -e '\\->' | xargs git grep $@; };f "
grep-branch-remote = "!f(){ git branch -a | sed -e 's/[ \\*]*//' | grep -v -e '\\->' | grep '^remotes' | xargs git grep $@; };f"
grep-branch-local = "!f(){ git branch -a | sed -e 's/[ \\*]*//' | grep -v -e '\\->' -e '^remotes' | xargs git grep $@; };f "
Note: When you add aliases and they fail to run - check backslashes \
they may require additional escape \\
in compare to bash commands.
Explanation:
git branch -a
- Display all branches;sed -e 's/[ \\*]*//'
- Trim spaces (from branch -a
) and *
, which is shown in front of the active branch name;grep -v -e '\\->'
- Ignore complex names likeremotes/origin/HEAD -> origin/master
;grep '^remotes'
- Get all remote branches;grep -v -e '^remotes'
- Get branches except remote branches;git grep-branch-local -n getTastyCookies
-n
Prefix the line number to matching lines.
[user@pc project]$ git grep-branch-local -n getTastyCookies
dev:53:modules/factory/getters.php:function getTastyCookies($user);
master:50:modules/factory/getters.php:function getTastyCookies($user)
The current structure is:
:
- Separator
dev
53
modules/factory/getters.php
function getTastyCookies($user)
As you should know: Bash commands should be stored in .sh
scripts or run in a shell.
git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' -e '^remotes' \
| xargs git grep "TEXT"
git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' | grep '^remotes' \
| xargs git grep "TEXT"
git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' \
| xargs git grep "TEXT"
Upvotes: 11
Reputation: 6912
I found this most useful (omit -i
if you desire a case-sensitive search):
git grep -i foo `git for-each-ref --format='%(refname)' refs/`
You'd need to adjust the last arguments depending on whether you want to only look at remote vs. local branches, i.e.:
git grep -i foo $(git for-each-ref --format='%(refname)' refs/remotes)
git grep -i foo $(git for-each-ref --format='%(refname)' refs/heads)
The alias I created looks like this:
grep-refs = !sh -c 'git grep "$0" "$@" "$(git for-each-ref --format=\"%(refname)\"" refs/)'
Upvotes: 37
Reputation: 90306
If you give any commit a SHA-1 hash value to git grep
you have it search in them, instead of the working copy.
To search all branches, you can get all the trees with git rev-list --all
. Put it all with
git grep "regexp" $(git rev-list --all)
... and have patience
Upvotes: 4
Reputation: 39253
Here's how I do it:
git for-each-ref --format='%(*refname)' | xargs git grep SEARCHTERM
Upvotes: 4
Reputation: 13916
git log
can be a more effective way of searching for text across all branches, especially if there are many matches, and you want to see more recent (relevant) changes first.
git log -p --all -S 'search string'
git log -p --all -G 'match regular expression'
These log commands list commits that add or remove the given search string/regex, (generally) more recent first. The -p
option causes the relevant diff to be shown where the pattern was added or removed, so you can see it in context.
Having found a relevant commit that adds the text you were looking for (eg. 8beeff00d), find the branches that contain the commit:
git branch -a --contains 8beeff00d
Upvotes: 103