The Reflog

The Reflog: Git's Safety Net

Every time a branch or HEAD moves, by a commit, checkout, merge, reset, rebase or pull, Git 1,932 appends a line to that ref's reflog: the old and new hash, who, when and why. git reflog shows HEAD's; name a branch to see its own:

Reading the reflogs of HEAD and mainShell
git reflog -2
git reflog -3 --date=iso --format='%h %gd' main
git rev-parse --short main@{2}
Output
035e659 HEAD@{0}: commit: Restore cents in prices: NUMERIC(8) meant whole dollars
c02cab3 HEAD@{1}: checkout: moving from a2ce60518618931de609c43945b1b2ed8b588f28 to main
035e659 main@{2026-09-25 15:20:00 +0800}
c02cab3 main@{2026-09-25 14:45:00 +0800}
340f3db main@{2026-09-25 14:35:00 +0800}
340f3db

HEAD@{1} is where HEAD was one move ago, here the end of the bisect in Automated Bisect; main@{2} is main two updates ago, and main@{yesterday} where it was at a time. These work in any command, which makes recovery a one-liner. Two limits matter. The reflog is local, never pushed or cloned. And it records ref movements, not files: uncommitted edits that git reset --hard threw away were never in it. Commit early, even as "WIP".