The name is the worst thing about git blame. The command does not exist to find someone to fault; it exists to answer the question every developer asks twenty times a week: why is this line here?
From line to decision#
git blame app/Models/Invoice.php
Every line comes back annotated with the commit that last touched it, the author and the date. The commit hash is the valuable part - follow it:
git show 8c6e7ec
Now you have the full diff, the commit message, and usually the pull request it came from. That chain - line, commit, message, PR - is the difference between staring at a strange condition and understanding the edge case it guards.
Two options earn their keep:
git blame -L 40,60 app/Models/Invoice.php # just these lines
git blame -w config/queue.php # ignore whitespace-only changes
-w matters more than it looks: without it, the last person to reindent a block “owns” every line in it.
Hide the reformat commit#
Every repo has one: the day the whole codebase was reformatted, and blame started pointing every line at it. Git has a built-in answer:
git config blame.ignoreRevsFile .git-blame-ignore-revs
Put the reformat commit’s hash in .git-blame-ignore-revs, commit the file, and blame skips those revisions on everyone’s machine. GitHub honours the same file in its blame view, so the fix works locally and in the browser.
When blame is the wrong tool#
Blame shows the last commit to touch a line. To find when something appeared or disappeared entirely - a setting, a constant, a call - the pickaxe is better:
git log -S 'QUEUE_CONNECTION' --oneline -- config/queue.php .env.example
The culture part#
Used as a name-and-shame tool, blame makes people defensive and teaches them to avoid touching old code. Used as a documentation tool, it does the opposite: the author of a line is the person most likely to remember the constraints behind it, and “what were we solving here?” gets a useful answer where “who broke this?” gets silence.
The habit to build is simple. When a line surprises you, blame it, read the commit, and ask about the decision - not the person.
Share this post
Keep reading
Git Bisect: Find the Commit That Broke It
The tests passed last week and fail now. Bisect turns 'somewhere in these 40 commits' into six test runs.
The Reflog: Undoing Almost Anything in Git
Reset too far, deleted the wrong branch, botched a rebase? The reflog remembers where HEAD has been, and that is usually enough.
What Not to Commit in a Laravel Project
vendor, .env, caches and build output: the short list of what stays out of the repo, and the .gitignore that keeps it out.