Search code examples
gitgrepdiff

How to grep (search through) committed code in the Git history


I have deleted a file or some code in a file sometime in the past. Can I search through the content (not just the commit messages)?

A very poor solution is to grep the log:

git log -p | grep <pattern>

However, this doesn't return the commit hash straight away. I played around with git grep to no avail.


Solution

  • You should use the pickaxe (-S) option of git log.

    To search for Foo:

    git log -SFoo -- path_containing_change
    git log -SFoo --since=2009.1.1 --until=2010.1.1 -- path_containing_change
    

    See Git history - find lost line by keyword for more.

    -S (named pickaxe) comes originally from a git diff option (Git v0.99, May 2005). Then -S (pickaxe) was ported to git log in May 2006 with Git 1.4.0-rc1.


    As Jakub Narębski commented:

    • this looks for differences that introduce or remove an instance of <string>. It usually means "revisions where you added or removed line with 'Foo'".

    • the --pickaxe-regex option allows you to use extended POSIX regex instead of searching for a string. Example (from git log): git log -S"frotz\(nitfol" --pickaxe-regex


    As Rob commented, this search is case-sensitive - he opened a follow-up question on how to search case-insensitive.


    Hi Angel notes in the comments:

    Executing a git log -G<regexp> --branches --all (the -G is same as -S but for regexes) does same thing as the accepted one (git grep <regexp> $(git rev-list --all)), but it soooo much faster!

    The accepted answer was still searching for text after ≈10 minutes of me running it, whereas this one gives results after ≈4 seconds 🤷‍♂️. The output here is more useful as well