Git & GitHub · lesson 9 of 12
Recovering Lost Commits with Reflog
Accidentally discard a commit with git reset --hard, watch it vanish from git log, then find and recover it with git reflog.
By SkillByExample · Published
git reset --hard looks destructive because the commit disappears from git log
immediately. It isn’t gone — the reflog remembers every place HEAD has pointed, and
this lesson uses it to undo a real mistake.
1) Commit something, then discard it by mistake
$ # ...edit scratch.py, add total()...
$ git commit -am "Add total() helper"
$ git log --oneline -1
3cb083d Add total() helper
$ git reset --hard HEAD~1
$ git log --oneline -1
73f7789 Add scratch calculation feature
3cb083d is gone from git log — as far as the normal history view is concerned, it
never happened.
2) The reflog remembers anyway
$ git reflog
73f7789 HEAD@{0}: reset: moving to HEAD~1
3cb083d HEAD@{1}: commit: Add total() helper
73f7789 HEAD@{2}: commit (amend): Add scratch calculation feature
26b7ef1 HEAD@{3}: rebase (finish): returning to refs/heads/main
Every move HEAD made on this machine is logged, most recent first — including the
reset itself. HEAD@{1} is exactly where HEAD pointed right before the reset:
3cb083d, the commit that seemed to vanish.
3) Recover it
$ git reset --hard HEAD@{1}
$ git log --oneline -2
3cb083d Add total() helper
73f7789 Add scratch calculation feature
Another reset --hard, this time aimed at the reflog entry instead of a branch or
commit hash, puts main right back where it was. Nothing was actually lost — the
commit object stayed on disk the whole time; only the branch pointer had moved away
from it.
Practice
-
Run
git reflogafter agit commit --amend(from the rewriting-history lesson) and find both the old and new commit listed — amend abandons a commit the same way reset does, and it’s recoverable the same way. -
Use
git branch recovered-work 3cb083d(a commit hash from the reflog, notHEAD@{1}) to create a new branch pointing at a “lost” commit instead of movingmainback — useful when you don’t want to disturb your current branch’s tip.Solution
$ git branch recovered-work 3cb083d $ git log --oneline recovered-work -1 3cb083d Add total() helpermainstays wherever it was; the lost commit is now reachable from a new branch. -
Run
git show HEAD@{2}to inspect a reflog entry from further back without resetting anything — reflog entries work anywhere a commit reference is expected. -
Deliberately lose an uncommitted change (edit a file, don’t commit, then
git reset --hard) and confirmgit reflogdoes not help recover it — it only tracks whereHEADand branches pointed, not working-directory content that was never committed. -
Run
git reflog show <branch-name>(rather than plaingit reflog, which defaults toHEAD) to see the movement history of a specific branch ref.