git bisect & blame Cheat Sheet
"It worked on Tuesday." Bisect finds the commit. Blame finds the author. Log and reflog cover everything else. The git rescue commands you'll use during incidents, on one page.
bisect, the four steps
Binary search across commits. With 1,024 commits between known-good and known-bad, you'll test ~10 to find the culprit. Without bisect, you're testing them all.
git bisect start, enter bisect mode. HEAD is the implicit "bad".git bisect bad, mark current commit as broken. Equivalent togit bisect bad HEAD.git bisect good v1.4.0, mark a known-good ref. Tag, branch, or SHA.- Git checks out the midpoint, you test it, mark
git bisect goodorgit bisect bad. Repeat until git prints "first bad commit". git bisect skip, can't test this revision (broken build, bad merge). Git picks another nearby commit.git bisect reset, exit bisect mode and return to where you were. Always run when done; otherwise you're stuck on a detached HEAD.
bisect run, automated
If you can write a script that exits 0 for "good" and non-zero for "bad", git will drive bisect for you. The win is enormous: 30-second test × 10 commits = 5 minutes of you doing nothing.
git bisect run ./test.sh, run the script at each midpoint; mark good/bad based on exit code; stop when found.git bisect run pytest tests/test_login.py, pytest exits non-zero on failure; that's all bisect needs.- Exit code 125 = "skip this commit" (build broken, etc.). Use it to keep bisect moving past unrelated breakage.
- Test scripts must be in your working tree but not version-controlled in the bisect range, put it in
/tmpor a separate worktree. git bisect log, the trail of good/bad marks. Save withgit bisect log > bisect.log; replay withgit bisect replay bisect.log.git bisect terms --term-old=working --term-new=broken, rename "good/bad" if you find them confusing for performance regressions where bigger isn't worse.
blame, who and when
blame's defaults are noisy. The flags below cut through formatting changes and refactor commits to find the actual semantic author of a line.
git blame -L 100,150 server.go, blame just lines 100–150. Use this; never blame a whole 2,000-line file.git blame -w server.go, ignore whitespace changes. Skips reformat commits.git blame -M server.go, detect lines moved within the file.-Cfor moves between files.-CCCfor aggressive cross-file detection.git blame --since=2026-01-01 server.go, only commits after a date. Useful when older history is noise.git blame --ignore-rev abc1234 server.go, pretend a commit didn't happen. Make a.git-blame-ignore-revsfile with reformat SHAs and addblame.ignoreRevsFile = .git-blame-ignore-revsto.git/config.git log -L 100,150:server.go, the history of just those lines. Often more useful than blame; shows the evolution.
log -p, what and why
blame tells you the commit; log -p shows the diff and the message that motivated it. The "why" is in the commit message; train your team to write good ones.
git log -p server.go, full history of one file with diffs.git log -p -S "doSomething", commits that added/removed the string "doSomething". The pickaxe; faster than browsing log.git log -p -G "regex", like-Sbut with regex. Finds commits where matched lines changed.git log --follow server.go, follow renames. Without this, log stops at the rename.git log --oneline --graph --all, the visual branch picture. Run when "where did this commit go?" comes up.git show abc1234, one commit's message + diff. The shorter cousin oflog -p.
reflog, undoing the undoing
The reflog is git's safety net. Anything HEAD has ever pointed to is recoverable from here, even after a hard reset. It expires after 90 days by default.
git reflog, the timeline of where HEAD has been. Most recent on top.git reset --hard HEAD@{2}, jump back to where HEAD was 2 moves ago. Recover from an accidental reset.git checkout HEAD@{2.hours.ago}, time-based reflog access. Rarely needed but very handy.git reflog show feature-branch, per-branch reflog. Useful when you accidentally--force'd something.git fsck --lost-found, surfaces dangling commits that aren't in any reflog. The last-resort recovery tool.- Lost a branch?
git branch recovered <sha-from-reflog>resurrects it.
stash recovery
Forgot what you stashed and dropped it? Still recoverable as long as gc hasn't run.
git stash list, current stashes. Each is a real commit under the hood.git stash show -p stash@{0}, full diff of a stash without applying.git fsck --no-reflog | grep dangling, SHAs of dropped stashes.git show <sha>on each, identify the right one by the diff.git stash apply <sha>, restore.git stash branch recovered <sha>creates a fresh branch from it.- Prevent the loss next time,
git stash push -m "wip-2026-04-26 jwt refactor". Named stashes are a lot easier to find later.