Find somethingAlways fixable

Find when a line, function or string was added or removed

How do I find which commit introduced a particular piece of code?

Short answer

git log -S "text" (the pickaxe) finds every commit where the number of occurrences of that string changed — which is how you locate the commit that introduced or deleted it. git log -L traces one function's entire evolution.

quick fix
git log -S "functionName" --oneline --all

Lists every commit that added or removed that string, across all branches

Does this match your situation?

  • You need to know why a strange line exists.
  • A config value appeared and nobody knows when.
  • You want the commit that deleted a function.
  • git blame only shows the last change, not the origin.

Step-by-step fix

  1. Use the pickaxe to find where a string appeared

    -S reports commits where the count of that string changed, so you get the commit that added it and the one that removed it — not every commit that happened to touch the same file.

    step 1
    git log -S "AudioManager" --oneline --all
    
    # see the actual change in each result:
    git log -S "AudioManager" -p
    
  2. Search by pattern instead of exact text

    -G takes a regular expression and matches against the diff itself, which is better when the exact spelling varies.

    step 2
    git log -G "api[_-]?key" --oneline --all
    
  3. Trace one function through its whole life

    -L follows a line range or a named function and prints every version of it in reverse order. It's the clearest way to understand how something evolved.

    step 3
    git log -L :calculateDamage:src/Combat.cs
    
    # or by line range:
    git log -L 40,60:src/Combat.cs
    
  4. Blame for the last change, then walk backwards

    Blame shows who touched a line most recently. To find the real origin, blame the parent of that commit and repeat until the line first appears.

    step 4
    git blame -L 42,45 src/Combat.cs
    # take the commit hash, then look before it:
    git blame -L 42,45 a1b2c3d^ -- src/Combat.cs
    
  5. Search the content of an old commit directly

    git grep works against any commit, so you can ask whether something existed at a given release without checking it out.

    step 5
    git grep "calculateDamage" v1.2.0
    git grep -n "TODO" $(git rev-list --all) | head
    

Why this works

git log normally filters by path, which tells you that a file changed but not what changed inside it. The pickaxe options work on the diff content instead: -S counts occurrences of a string in each commit's before and after states and reports only where that count differs, which isolates introduction and deletion precisely. -L goes further and reconstructs the history of a specific range by following it backwards through renames and edits, which is why it can show a function's entire evolution in one pass.

How to stop it happening again

  • Write commit messages explaining why, so this archaeology is rarely needed.
  • Keep commits focused - a 200-file commit tells you nothing about intent.
  • Add a .git-blame-ignore-revs file so formatting runs don't bury real authorship.

Commands used in this guide

git log

Browse commit history with as much or as little detail as you want.

git blame

Show which commit and author last touched every line of a file.

git grep

Search the contents of tracked files - at any point in history.

git show

Display a single commit, tag or file-at-a-commit in full.

git bisect

Binary-search your history to find the exact commit that introduced a bug.

Still stuck?

Search the full command reference and every other rescue guide — there are 56 of them, covering everything from detached HEAD to force-push disasters.

Browse all guides →

Frequently asked questions

How do I find the commit that added a specific line of code?

git log -S "the exact text" --oneline --all lists every commit where the number of occurrences of that string changed, which pinpoints where it was introduced and where it was removed. Add -p to see the diffs.

What is the difference between git log -S and -G?

-S counts occurrences of a fixed string and reports commits where that count changed, so it finds additions and deletions. -G matches a regular expression anywhere in the diff, so it also catches commits that merely modified a line containing the pattern.

How do I see the full history of one function?

git log -L :functionName:path/to/file traces that function through history, printing each version. If Git can't detect the function boundaries for your language, use a line range instead: git log -L 40,60:path/to/file.

Related rescue guides

← All Git Rescue guides