git reflog: undo almost anything
You just ran git reset --hard and your commits are gone. Or you did a rebase and everything went sideways. Or you deleted a branch with work on it. The standard git log shows nothing — those commits have vanished.
Except they haven't. Git never truly deletes commits. The reflog records every position your HEAD has been in — every commit, reset, rebase, checkout, merge. It's your time machine.
See where you've been
The output looks like this:
a1b2c3d HEAD@{0}: reset: moving to HEAD~3
f4e5d6a HEAD@{1}: commit: add user authentication
b7c8d9e HEAD@{2}: commit: fix login redirect
Each line is a snapshot. HEAD@{1} is where you were one action ago. The commit hashes on the left are still valid — the commits still exist in git's object store.
Recovering from common disasters
Undoing a git reset --hard:
git reflog # find the commit before the reset
git reset --hard HEAD@{1} # go back to it
Recovering a deleted branch:
git reflog # find the last commit on that branch
git checkout -b recovered HEAD@{4} # recreate the branch at that point
Undoing a bad rebase:
git reflog # find the commit before the rebase started
git reset --hard HEAD@{5} # jump back to pre-rebase state
The mental model
Think of the reflog as an undo history for git itself. git log shows your project's history. git reflog shows your history — every action you took, in order, with the ability to jump back to any point.
z to undo — it uses the reflog under the hood. Same concept, visual interface.For the full reference, see our git cheatsheet and git rebase guide.