git command to find when a line mentioning “string” was removed from a file on main


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.

(git-log documentation)

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.


Leave a Reply