Find somethingAlways fixable

Stop a reformatting commit ruining git blame

Someone ran Prettier over the whole repo and now git blame shows only their name — how do I see the real authors?

If you’re seeing this error

fatal: could not open object name list: .git-blame-ignore-revs

You’re in the right place — the fix is below.

Short answer

Put the hash of the reformatting commit in a file called .git-blame-ignore-revs, then set blame.ignoreRevsFile to it. Blame steps straight past that commit and attributes each line to whoever last changed it meaningfully. GitHub and GitLab both read the same file automatically.

quick fix
echo "<reformat-commit-hash>" >> .git-blame-ignore-revs
git config blame.ignoreRevsFile .git-blame-ignore-revs
git blame src/app.ts

One file, one setting — and hosted blame views honour it too

Does this match your situation?

  • Every line in a file is attributed to one commit titled 'chore: run prettier'.
  • A whitespace, tab-to-space or line-ending migration has flattened the history.
  • git blame is useless for working out why a line exists.
  • 'fatal: could not open object name list: .git-blame-ignore-revs'

Step-by-step fix

  1. Find the commit that flattened everything

    Blame the file and look at what dominates it. Once you have the hash of the reformatting commit, everything else follows.

    step 1
    git blame src/app.ts | head -20
    git log --oneline --all --grep='format\|prettier\|lint' -i -n 20
    
  2. Create the ignore file

    Full 40-character hashes only — abbreviations are rejected. Comments are allowed and worth writing, because in a year nobody will remember what each hash was.

    step 2
    cat > .git-blame-ignore-revs <<'EOF'
    # Migrate to Prettier across the codebase
    2b4a8d1f9c3e5a7b1d0f8e6c4a2b9d7f1e3c5a8b
    
    # Convert tabs to spaces
    9f3e1c7a5b2d8f4e6a0c9b3d7f1e5a8c2b4d6f0a
    EOF
    git add .git-blame-ignore-revs
    git commit -m "chore: ignore formatting commits in blame"
    
  3. Tell Git to use it

    Set it in the repository so it applies to every blame you run there. Committing the file means teammates only need this one command, and many will get it for free from their host's web view.

    step 3
    git config blame.ignoreRevsFile .git-blame-ignore-revs
    git blame src/app.ts
    

    GitHub and GitLab both detect .git-blame-ignore-revs automatically in their blame views — no configuration needed there.

  4. Ignore a commit without any setup

    For a one-off investigation you do not need a file at all. --ignore-rev takes a hash directly.

    step 4
    git blame --ignore-rev <hash> src/app.ts
    git blame --ignore-revs-file .git-blame-ignore-revs src/app.ts
    
  5. Ignore whitespace changes entirely

    Independent of the ignore file, -w tells blame to disregard whitespace-only differences. Combining it with -C and -M also follows lines through moves between files, which is where most 'who wrote this?' questions actually end up.

    step 5
    git blame -w src/app.ts
    git blame -w -C -C -M src/app.ts
    git log -p --follow -- src/app.ts
    

Why this works

Blame works by walking history and asking, for each line, which commit last touched it — so a commit that rewrites every line in the repository genuinely is the last one to touch all of them. The information is not lost; it is one layer down, behind a commit that changed presentation rather than meaning. blame.ignoreRevsFile makes that distinction explicit: for the listed commits, blame attributes each line to the commit before instead. The mechanism is deliberately opt-in and stored in the repository rather than inferred, because Git cannot tell a purely cosmetic change from a real one — only the people who made it can, which is why the file is something you curate as your codebase gets reformatted.

If that didn’t work

  • 'could not open object name list' means the path is wrong or the file is not committed on this branch.
  • Hashes must be the full 40 characters; short ones are silently unusable.
  • git log -S'<code>' finds the commit that introduced a string regardless of formatting churn.
  • For a file rewritten wholesale, git log --follow -p often reads better than blame.

How to stop it happening again

  • Add the hash to .git-blame-ignore-revs in the same pull request that does the reformatting.
  • Keep formatting changes in their own commit, never mixed with logic.
  • Adopt a formatter early and enforce it in CI so there is one flattening commit rather than many.
  • Set blame.ignoreRevsFile in the repository config so nobody has to remember the flag.

Commands used in this guide

git blame

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

git log

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

git config

Read and write Git settings for one repo, your user, or the whole machine.

git diff

Show exactly what changed - between your files, the index, commits or branches.

git grep

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

Still stuck?

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

Browse all guides →

Frequently asked questions

How do I make git blame skip a formatting commit?

List its full 40-character hash in .git-blame-ignore-revs and run git config blame.ignoreRevsFile .git-blame-ignore-revs. Blame then attributes each line to the last commit that changed it meaningfully rather than to the reformat.

Does GitHub respect .git-blame-ignore-revs?

Yes. GitHub and GitLab both pick the file up automatically in their blame views once it is committed to the default branch, so the fix applies to the web interface as well as the command line.

What is the difference between git blame -w and the ignore-revs file?

-w ignores whitespace-only differences on the fly, which handles indentation churn. The ignore file skips entire named commits, which is what you need when a formatter rewrote quotes, line breaks or import ordering — changes that are not whitespace but still carry no meaning.

Why does Git say it could not open the object name list?

blame.ignoreRevsFile points at a path that does not exist on the current branch, usually because the file has not been committed yet or you are on an older branch. Commit the file, or unset the config with git config --unset blame.ignoreRevsFile.

Can git blame follow a line that moved to another file?

Yes — git blame -C -C -M looks for the line in other files and in earlier commits. It is slower, but it is what finds the real author when code has been extracted into a new module.

Related rescue guides

← All Git Rescue guides