Git Blame
git blame shows who last changed each line of a file, and which commit did it.
git blame annotates a file line by line, telling you which commit last touched
each line and who wrote it. It answers "why is this here" with a commit hash
rather than a guess.
The basic form
git blame src/index.ts
Each line is prefixed with the abbreviated commit hash, the author, a timestamp, and the line number. The pointer format is configurable, which matters because the default is hard to read in a wide line.
Better output
git blame -w src/index.ts # ignore whitespace-only changes
git blame -w -C -C -C src/index.ts # also try moving lines between files
git blame -L 20,40 src/index.ts # only lines 20 to 40
git blame -C src/index.ts # who last wrote this much of the file
-w is the one that makes blame useful. Without it, a file reformatted by a
formatter appears to be entirely rewritten, and you learn nothing. With it, and
-C to follow lines that moved, blame points at the commit that actually
introduced the logic.
git blame -w -C -C -C is the common incantation, and it is worth having in
your fingers.
From a blame to the change
The hash in the margin is a commit, so the next command is usually git show:
git show a1b2c3d
Why a line is there
git blame answers who last changed a line, not why it exists. A line nobody
remembers writing is usually a fix for a bug nobody wrote down, which is what
git log -S "<string>" is for — it finds the commits that added or removed a
literal string:
git log -S "retryCount" --oneline
Only your changes
git blame --author="Vicky" src/index.ts
Interactive: git gui blame
Some terminals have a mode that walks the history of a single line as you move
through the file. In VS Code, the GitLens extension provides the same thing. Both
are far quicker than reading hashes and running git show on each.
A caveat
Blame attributes the last commit to touch a line, not the person who wrote the
original logic. A one-character fix on a line makes the fix's author the blame
for the whole line, which is why -w and -C exist — and why reading the commit
is part of using the output. See
Git Show and
History.