We have to admit it, git has become the de facto tool in the open source ecosystem. How many projects are now only on Github? Why do the open source communities only swear now by this tool, instead of the well known Subversion and CVS? Simply because git is much more powerful and quickly became an essential tool for all developers. The following tips will help you search a git repo like a ninja.
First let’s begin with:
Try it out on a project, then try the same search with ack and grep and you see that we have speed that’s better than either grep or ack. First, we’ll make some improvements.
Allow extended regular expressions:
git config --global grep.extendRegexp true
Git can also support full blown Perl regular expressions as well, by compiling git with libpcre. Easy for homebrew users:
brew install git --with-pcre
Always include line numbers:
git config --global grep.lineNumber true
Group output like ack:
git config --global alias.g "grep --break --heading --line-number"
As far as I know there is no non-trivial way to add default arguments/override git commands, plus g is nice and short.
The speed of git grep, which is basically a product of it being implemented in C and only searching your project files, i.e. not files in .git, is alone very compelling, but where git grep becomes really interesting and powerful is allowing you to interface with your repo’s git database.
Here’s a list of commands made up of different arguments and concepts of git grep and git log that you will be able to reuse/use as instruction to reformulate later.
git grep -e my_other_branch -- '*.js'
The — signals the end of options, that the rest of the paramaters are limiters.
Search files registered in the index, rather than the working tree:
git grep --cached -e
Note: We’re searching what’s registered in the index rather than what is staged!
Search for staged files containing a regexp that was either added or removed:
git diff-index --cached -G HEAD | cut -f2
Search through previous revisions whose contents contain a given regexp:
git grep $(git rev-list --all)
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 $rev; done)
Search for commits whose changes include your regexp:
git log -G
Combine regexps and filter results via boolean logic:
git grep -e 'include' --or 'extend' --and \( -e 'Specification' -e 'Factory' \)
Here we search for places that we extend or include, either specifications or factories:
module UserSpecification; end module UserFactory; end module Bad; end class User extend UserSpecification include UserFactory include Bad end
Given this file, after running the command above, find files that contain some terms, not necessarily on the same line:
git grep -e --and -e
Note: If this is not what you want, as it will search for lines that contain both those regular expressions, this is what we want to search for all matches occurring somewhere in the file:
git grep --all-matches -e -e
Find commits whose message mention login and were authored by “Kevin” in the last month:
git log --grep=login --author=kevin --since=1.month
Text Editor Integration
Inevitably we will want to be able to search and use these programs from within our text editors.
Vim users have it pretty good, with both ack.vim and Tim Pope’s fugitive.vim which includes :Ggrep to interface with git grep by being to search and have your results listed and linked in the quickfix window. By listing the results in the quickfix window this mean you have the usual quickfix navigation keybindings, if you’re unfamiliar, see :h quickfix
If your project is not under git version control than you can use ack.vim in a similar manner:
Emacs user’s have had vc-git-grep built-in since v22.1 and it’s very similar to :Ggrep. And for acking there is full-ack. See this page (or C-h f compilation-mode) for info on navigating in compilation-mode (the mode that both vc-git-grep and full-ack output into).
By now you are comfortable with git grep and git log, and can get more details on each of these commands via git help [command], and have some useful tools in your repertoire, now have fun!
Final note: Please don’t forget to keep git updated at all times.
Inspiration & Original Source: 1 Travis Jeffery