← back to latest

Search your Git history for a deleted function or string

git log -S"handleAuth" --oneline --all

anatomy

git log
Walk the commit history and print matching commits. Without filters it dumps everything, so the useful part is narrowing it down.
-S"handleAuth"
The pickaxe. Show only commits where the number of occurrences of the string changed, meaning it was added or removed. This is how you find the commit that deleted a function.
--oneline
One commit per line: abbreviated hash and subject. Keeps the output scannable when the history is long.
--all
Search every branch and tag, not only the current branch. The commit you need is often on a branch that was merged and deleted.

Sample output

a1c3e7f Remove legacy auth middleware
f4d219b Refactor login flow to use OAuth
83b6a02 Add handleAuth function for session tokens

Three commits touched the string handleAuth. Read from the bottom up: 83b6a02 added it, f4d219b changed how many times it appeared, and a1c3e7f removed it entirely. Run git show a1c3e7f to see exactly what was deleted.

When you would reach for it

Someone removed a function or a config block and nobody remembers when or why. A test references a helper that no longer exists. You are tracking down when a feature flag was introduced or retired. The pickaxe answers “which commit changed the presence of this string” across the entire history, which is a different question from grep and one that is harder to answer any other way.

Gotchas

  • -S counts occurrences, so a commit that renames handleAuth to handleAuthentication will show up twice: once for removing the old string, once for adding the new one. If that is confusing, use -G"handleAuth" instead, which matches any diff line containing the pattern.
  • On large repositories the search can be slow because Git walks every commit and diffs every changed file. Adding a path at the end (git log -S"handleAuth" --oneline -- src/auth/) narrows the search to one directory and speeds it up considerably.
  • The string match is literal by default. If you need a regex, use -G instead of -S. The two flags are not interchangeable: -S counts occurrences per file, -G greps diff lines.
  • --all includes stash refs and remote-tracking branches. If the output is noisy, drop --all and search only the current branch.

Variants

$ git log -S"handleAuth" -p --all -- src/

Show the full diff for each matching commit, scoped to the src/ directory. Useful when you need to see the surrounding code, not only the commit message

$ git log -G"handle[A-Z].*auth" --oneline --all

Regex search across diffs. Finds any line where a pattern was added or removed, regardless of exact spelling

$ git log -S"handleAuth" --oneline --all --diff-filter=D

Show only commits that deleted a file containing the string. Narrows the results when you know the whole file was removed, not a single function

lineage

Git's pickaxe search traces back to a concept Junio Hamano brought from his earlier work on the diff machinery. The name comes from the original implementation in a pre-Git tool where you would use -S to 'pick through' diffs looking for a specific string. When Hamano became Git's maintainer in 2005, the pickaxe became part of git log and git diff. The idea is distinct from grep: rather than searching file contents at a single point in time, it searches the deltas themselves, finding the moments when a string entered or left the codebase. The -G variant, which matches diffs by regex rather than counting occurrences, was added later to cover cases where the string moved or changed form rather than appearing or disappearing outright.