Lesson 6 of 7 · 9 min
Recovery and investigation
The reflog, bisect, blame and stash — how to find what broke and get back what you lost.
The reflog is the safety net
Every time HEAD moves — commit, checkout, reset, rebase, merge — Git appends the previous position to the reflog. A bad reset, a rebase that dropped a commit, a deleted branch: the old commit is still in the object database and the reflog still names it.
It is local and expires after about 90 days by default. It cannot recover work that was never committed, which is the one thing to remember.
git reflog # every position HEAD has held
# a1b2c3d HEAD@{0}: reset: moving to HEAD~3
# 9f8e7d6 HEAD@{1}: commit: the work I just lost
git reset --hard HEAD@{1} # back to before the reset
git branch recovered 9f8e7d6 # or give the commit a name
git fsck --lost-found # for objects with no reflog entryrevert versus reset
revert creates a new commit that undoes an earlier one, leaving history intact. It is the correct way to undo anything already pushed, because it adds rather than rewrites.
Reverting a merge commit needs -m 1 to say which parent is the mainline. And once a merge is reverted, re-merging that branch later does nothing — the commits are already ancestors. You revert the revert.
git bisect start
git bisect bad HEAD # broken here
git bisect good v2.3.0 # working here
git bisect run npm test -- --silent # Git drives the search
# Exit 0 = good, 1-124 = bad, 125 = skip this commit.
git bisect reset # back to where you startedNote: 1000 commits take about ten steps. Automating it with the failing test is what makes bisect worth reaching for.
Blame, and seeing past reformatting
git blame shows which commit last touched each line, but a formatting sweep makes every line look recently changed. Adding -w ignores whitespace, and --ignore-rev with a revs file lets you permanently skip known formatting commits.
git log -S 'someString' searches for commits that changed the number of occurrences of a string — the fastest way to find when a function was introduced or removed, and far more useful than scrolling the log.
Worth remembering
- The reflog records every position HEAD held, so almost nothing is truly lost.
- bisect finds the breaking commit in log₂(n) steps and can be fully automated.
- revert is the safe undo for published history; reset is for local history.
Test it now
Recovery scenarios and history archaeology fill much of the hard bank.