History, diff, and blame
Introduction
Once you have commits, Git becomes a time machine: browse history, compare versions, and see who last changed each line. This chapter covers git log, git show, git diff, and git blame—the commands you use daily during code review and debugging.
Prerequisites
- Your First Commit Workflow
- A practice repo with at least two commits
git log Variations
Full log:
git logOne line per commit:
git log --onelineWith branch graph:
git log --oneline --graph --decorate --allCode explanation:
--graph— ASCII branch/merge lines--decorate— shows branch and tag names--all— every branch, not only current
Limit count:
git log -3
git log --since="2 weeks ago"Filter by author or message:
git log --author="Ada"
git log --grep="login"git show One Commit
Latest commit:
git showSpecific commit:
git show a1b2c3dCode explanation:
- Shows metadata, message, and patch (line-by-line diff for that commit)
Name-only or stats:
git show --stat a1b2c3d
git show --name-only a1b2c3dgit diff: Three Comparisons
Working tree vs staging area
What you would commit if you ran git add now on unstaged edits:
git diffStaging area vs last commit
What your next git commit will include:
git diff --stagedAlias used by many: git diff --cached (same meaning).
Working tree vs last commit
Everything changed since HEAD (staged + unstaged):
git diff HEADCompare two commits
git diff a1b2c3d..e4f5g6h
git diff main..feature/loginCode explanation:
A..B— changes from A’s tip to B’s tip- Useful for PR review before merge
Reading diff Output
diff --git a/src/index.js b/src/index.js
--- a/src/index.js
+++ b/src/index.js
@@ -1 +1 @@
-console.log('hello');
+console.log('hello git');| Prefix | Meaning |
|---|---|
- red line | Removed |
+ green line | Added |
@@** | Line number context |
git blame Line History
Who last touched each line of a file:
git blame src/index.jsSpecific lines:
git blame -L 10,20 README.mdCode explanation:
- Each line shows commit hash, author, date, and content
- Use when debugging “when did this bug get introduced?”
Ignore whitespace-only changes:
git blame -w src/index.jsTip
Blame Is Not Shame
blame finds context for fixes—it does not assign fault in code review.
Useful Combinations
# What changed in last commit?
git show HEAD
# Files changed between releases
git diff v1.0.0..v1.1.0 --stat
# Find commit that added a string (pickaxe)
git log -S "console.log" --oneline-S searches history for commits that add or remove a string—powerful for archaeology.
Workflow Example
git status
git diff
git add src/index.js
git diff --staged
git commit -m "Refactor index entry point"
git log --oneline -5Review diffs before commit to catch debug prints and secrets.
FAQ
log opens pager and I am stuck?
Press q to quit. Or git --no-pager log --oneline.
diff shows nothing?
No differences in that comparison—or file is untracked (git diff does not show untracked until add).
blame shows wrong person?
They made the last edit to that line; earlier authors lost in blame until you dig with log -L.
Compare to remote branch?
git diff origin/main..HEAD after git fetch.
Pretty log format?
git log --pretty=format:"%h %s" — customize columns.
GUI alternatives?
gitk, VS Code Source Control timeline, GitHub compare view—same data.