DEV Community

Igor Irianto
Igor Irianto

Posted on • Updated on • Originally published at irian.to

Learn git-grep to boost your command line search!

When searching for contents inside files from command-line, we probably think of find and grep, but how many of us have heard about git grep?

When searching inside your work tree, I found it more convenient than find/ grep. Here is how you can get started with git-grep today!

Things to know

Git grep searches inside project with git. The only requirement is the project need to be tracked (hint: git add .). It will work without having to commit it.

Let's git greppin'

The pattern is very simple. Do git grep {pattern} anywhere inside your project directory.

  • To search for "foo":
git grep foo
Enter fullscreen mode Exit fullscreen mode

Here are other useful variants:

  • Search with line number
git grep -n foo
Enter fullscreen mode Exit fullscreen mode
  • Returning only file name:
git grep -l foo
Enter fullscreen mode Exit fullscreen mode
  • It is regex-compatible.
git grep "f[^\s]*\s"
Enter fullscreen mode Exit fullscreen mode
  • To tell how many match in each file:
git grep -c foo
Enter fullscreen mode Exit fullscreen mode
  • To only look under certain file extension (ignore matches from other files)
git grep foo *.js
Enter fullscreen mode Exit fullscreen mode

and / or

  • To search for "foo" or "bar", we can do:
git grep -e foo -e bar
Enter fullscreen mode Exit fullscreen mode
  • To search for a file containing "foo" and "bar" and they are on the same line:
git grep -e foo --and -e bar
Enter fullscreen mode Exit fullscreen mode

To search for a file containing "foo" and "bar", not necessarily on the same line:

git grep --all-match -e foo -e bar
Enter fullscreen mode Exit fullscreen mode

There are more (check man git-grep, but above are the ones I find useful).

Getting fancy: search within and between commits

The real power of git grep is its ability to search inside ANY commit we want.

Here are the two that I found very useful:

  • Search inside specific commit

There are two ways to do it: reference it relative to HEAD and reference its SHA.

git grep "foo" HEAD~1 // search ONLY in one commit before current head
git grep "foo" a1b2 // search ONLY in commit a1b2
Enter fullscreen mode Exit fullscreen mode
  • Search inside multiple commits

It also accepts multiple commit references.

git grep "foo" HEAD HEAD~1 HEAD~7 // search in current head, previous head, and 7th from head.
git grep "foo" a1b2 HEAD~5 // search inside a1b2 SHA and 5th from head
Enter fullscreen mode Exit fullscreen mode
  • Search everything between 2 commits

This uses git rev-list command. Here are some quick refreshers:

git rev-list HEAD~3..HEAD // Returns all commits between HEAD~3 and HEAD.
git rev-list --all // Returns ALL Commits from the dawn of time to present day.
Enter fullscreen mode Exit fullscreen mode

Combining rev-list with git-grep, we can do:

  • Search for all occurrences of "foo" between HEAD~3 and HEAD
git grep foo $(git rev-list HEAD~3..HEAD)
Enter fullscreen mode Exit fullscreen mode
  • Search for ALL occurrences of "foo" from the very beginning to current.
git grep foo $(git rev-list --all)
Enter fullscreen mode Exit fullscreen mode

Of course, we can put together everything we learned. This returns filename(s) from every single commit we have that contain, in each file, "bar" and anything that matches f[^\s]*\s pattern.

git grep --all-match -l -e "f[^\s]*\s" -e bar $(git rev-list --all)
Enter fullscreen mode Exit fullscreen mode

That's it! I find git grep more convenient than traditional grep or find when I need to search file contents inside working tree. Of course, find/grep have their own usage that git grep can't do, but that's for another time.

Resources

Happy hacking!

Top comments (2)

Collapse
 
bootcode profile image
Robin Palotai

Good to know about the version search! Thank you.

Recently I learned about ripgrep (rg) which is a super nice substitute for grep.

Collapse
 
iggredible profile image
Igor Irianto

This one? I never heard of this before - and it has >>10k stars!! Wow! Gonna read it today.
Thanks for sharing!!!