Additions and updates to a line are easy, because you can just git blame
on the file in question and find who and/or what is responsible for the latest change. However, it’s hard to git blame
a line that was removed, right?
git log -S<string>
Look for differences that change the number of occurrences of the specified <string> (i.e. addition/deletion) in a file. Intended for the scripter’s use.
It is useful when you’re looking for an exact block of code (like a struct), and want to know the history of that block since it first came into being: use the feature iteratively to feed the interesting block in the preimage back into
-S
, and keep going until you get the very first version of the block.Binary files are searched as well.
You can use git log
with the -S
option (pickaxe) to find when “uuidtools” was removed:
git log -S"uuidtools" --oneline -- chef.gemspec
This will show all commits that added or removed “uuidtools” from chef.gemspec
. The commit where it was removed will show the line disappearing.
For more detail, add -p
to see the actual changes:
git log -S"uuidtools" -p -- chef.gemspec
If you want to search specifically on the main
branch:
git log main -S"uuidtools" -p -- chef.gemspec
The -S
option finds commits where the number of occurrences of “uuidtools” changed, so you’ll see both when it was added and when it was removed.
What if I want to use a regex?
git log -G<regex>
Look for differences whose patch text contains added/removed lines that match <regex>.
To illustrate the difference between
-S
<regex>--pickaxe-regex
and-G
<regex>, consider a commit with the following diff in the same file:+ return frotz(nitfol, two->ptr, 1, 0); ... - hit = frotz(nitfol, mf2.ptr, 1, 0);
You can use git log
with the -G
option to search by regex:
git log -G"uuidtools" --oneline -- chef.gemspec
The -G
option looks for commits where the regex matches in the diff, rather than just counting occurrences like -S
does.
For more detailed output with the actual changes:
git log -G"uuidtools" -p -- chef.gemspec
Or on the main
branch specifically:
git log main -G"uuidtools" -p -- chef.gemspec
The difference between -G
and -S
:
-G<regex>
: Finds commits where the regex matches any added or removed line-S<string>
: Finds commits where the number of occurrences of the string changed
So -G
is more flexible and will catch any line change matching your pattern, even if the total count stays the same.