Git Blame
Showing, for every line of a file, the commit and author that last changed it, the starting point for finding out why code is the way it is.
Git blame shows, beside each line of a file, which Commit last changed it, who made that commit, and when. Other version control systems call it annotate or praise. Despite the name, its real use is not assigning fault but recovering context: the commit behind a line carries its message, the Pull Request it came from, and the discussion around it, which usually explain why the code is the way it is.
That matters because code often looks wrong for reasons that are no longer visible. A strange special case may be the fix for a production incident, a workaround for a browser bug, or a requirement from a customer long gone. Chesterton's Fence applies: don't remove it until you know why it was put there. Blame is the fastest way to find out, and it is why atomic commits with good messages pay off years later.
Blame has blind spots:
- It shows the last change only. If someone reformatted the file or renamed a variable, blame points at them, not at whoever wrote the logic. Tools let you blame the parent of a commit to step further back, and
.git-blame-ignore-revstells Git to skip known mechanical commits such as a Code Formatter run. - Moved code. By default a line moved between files looks newly written. Options such as
-Mand-Cdetect lines moved or copied from elsewhere. - Squashed history. A Squash Merge collapses a branch into one commit, so blame lands on the merge rather than on the individual steps, though the pull request link usually survives.
- Deleted lines. Blame only explains lines that still exist. To find when something disappeared, search history with
git log -Sfor the text, or use Git Bisect to find the commit that changed behavior.
Using blame well is part of what is sometimes called code archaeology: reading history, old issues, and design notes to reconstruct decisions. It pairs with a characterization test when working on legacy code: blame says why the code was written, the test pins down what it currently does.
The name invites misuse. Treating blame output as evidence of who to fault discourages people from touching risky code, the opposite of the culture a Blameless Postmortem tries to build, and it misleads anyway, since the last person to touch a line often only moved it. Judging the person rather than the circumstances is the Fundamental Attribution Error in a terminal.
Where history is thin, as in code copied in from elsewhere or after a migration from another system, blame has nothing to offer, which is an argument for preserving history when moving repositories.
See also1
Linked from7
- Atomic CommitVersion Control & Delivery
A commit containing exactly one logical change, complete and independently sound.
- Chesterton's FenceMethod
Do not remove something whose purpose you cannot explain.
- Code FormatterVersion Control & Delivery
A tool that rewrites source code into one canonical layout automatically, ending style debates in code review and keeping diffs focused on what changed.
- Commit MessageVersion Control & Delivery
The note attached to each change in version control, conventionally a short summary line and a body explaining why, which becomes the main record of intent for anyone who later wonders why the code is the way it is.
- DiffVersion Control & Delivery
The listing of changes between two versions of a file, the algorithms that compute it, and the unified format that code review, patches, and merges are built on.
- Shallow CloneVersion Control & Delivery
Ways to fetch less than a whole Git repository, by cutting history, deferring file contents, or checking out only some directories, and what each breaks.
- Squash MergeVersion Control & Delivery
Collapsing a branch's commits into one before merging, trading granularity for a clean main history.