This should be one of the core features of Git, but for some reason it's impossible to figure out how to search for a string in your commit history and see the diffs that that string is in. Here's the best I've come up with:
To find which commits and which files a string was added or removed in:
git log -S'search string' --oneline --name-status
To see the diff of that
git log -S'search string' -p | grep 'search string' -C5
You can also do a regex search by using -G instead of -S.
On that same StackOverflow issue that @raedbenz linked, there is a better answer that basically suggests the same -S 'pickaxe' method described here + goes into some more details about it's usage:
* https://stackoverflow.com/questions/2928584/how-to-grep-search-committed-code-in-the-git-history/2928721#2928721
Since I always find myself ending up back on this gist, here are the methods described in that StackOverflow:
You should use the pickaxe (
-S) option ofgit log. To search for Foo:git log -SFoo -- path_containing_change git log -SFoo --since=2009.1.1 --until=2010.1.1 -- path_containing_changeSee Git history - find lost line by keyword for more. 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-regexoption allows you to use extended POSIX regex instead of searching for a string. Example (fromgit 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.
Looking at the StackOverflow for case-insensitive pickaxes search:
The way the -i is used with pickaxe (see commit accccde, git 1.7.10, April 2012) is:
git log -S foobar -i --oneline # or git log --regexp-ignore-case -Sfoobar # or git log -i -SfoobarNote that with 1.x git versions this option will not work with a regexps, only with a fixed string. It works with regexps only since git 2.0 and commit
218c45a, git 2.0, May 2014.
From:
My favorite way to do it is with
git log's-Goption (added in version 1.7.4).-G<regex> Look for differences whose added or removed line matches the given <regex>.There is a subtle difference between the way the
-Gand-Soptions determine if a commit matches:
- The
-Soption essentially counts the number of times your search matches in a file before and after a commit. The commit is shown in the log if the before and after counts are different. This will not, for example, show commits where a line matching your search was moved.- With the
-Goption, the commit is shown in the log if your search matches any line that was added, removed, or changed.
You can combine -p / --patch with any of these methods to get a diff patch of the found commits.
Hopefully saves someone else (or future me) some time! 🖤