Concept · How Git works

The reflog

Git’s record of everywhere HEAD and each branch has pointed — how you get back a commit you “lost”.

3 minrecover lost commitORIG_HEADundo resetundo rebase

Whenever HEAD or a branch moves (commit, reset, rebase, merge, checkout, amend), Git appends a line to that ref's reflog. It's a local diary of where your refs have been:

bash
$ git reflog
9f2c1e7 (HEAD -> main) HEAD@{0}: reset: moving to HEAD~3
c81d4a2 HEAD@{1}: commit: Add password reset email
5b0e9f1 HEAD@{2}: commit: Add password reset form
2a7c3d8 HEAD@{3}: rebase (finish): returning to refs/heads/main

Commits don't disappear when no branch points to them any more. They stay in the object store until garbage collection removes unreachable objects, which by default happens only after their reflog entries expire (about 30 days for unreachable commits, 90 days otherwise). The reflog is how you find them again.

Recovering

Undo a bad reset --hard:

bash
git reflog                      # find the commit from before the reset: c81d4a2
git reset --hard c81d4a2        # move the branch back (or: git reset --hard HEAD@{1})

Undo a rebase that went wrong:

bash
git reflog                      # find "rebase (start)" and take the entry just before it
git reset --hard HEAD@{5}
# or, immediately after the rebase:
git reset --hard ORIG_HEAD      # reset, rebase and merge save the previous position here

Get back commits made on a detached HEAD, or on a branch you deleted:

bash
git reflog                      # find the last commit
git switch -c recovered 5b0e9f1

git reflog show feature-x shows one branch's own history, which helps after it has been reset or rebased several times.

Limits

  • Local only. The reflog isn't pushed or cloned. It knows what happened in your repository, not what a teammate did.
  • Only commits. Changes that were never committed, such as edits wiped by reset --hard or restore, were never in the object store. git stash before risky operations protects them, and stashes are commits.
  • Entries expire. Recover soon rather than months later.

The reflog makes most of Git's history-rewriting commands safe to try: rebase, amend and reset can all be undone. It doesn't help once you've force-pushed over someone else's commits, which is why the golden rule of rebasing still applies.

Learn it in depth