How it works
The explanation, with examples you can run.
Lose three commits, then find them
git init -q -b main demo && cd demofor n in 1 2 3; do echo "v$n" > notes.txt; git add notes.txt; git commit -q -m "Notes v$n"; donegit reset --hard HEAD~2git log --onelineHEAD is now at 46f1e57 Notes v146f1e57 Notes v1git log follows parents from the branch tip, so v2 and v3 have disappeared from view. The reflog has not forgotten:
git reflog46f1e57 HEAD@{0}: reset: moving to HEAD~2a8c64d8 HEAD@{1}: commit: Notes v3d4cbec6 HEAD@{2}: commit: Notes v246f1e57 HEAD@{3}: commit (initial): Notes v1HEAD@{n} means "where HEAD was n moves ago". One move ago it was at v3, so reset back to that:
git reset --hard 'HEAD@{1}'git log --onelineHEAD is now at a8c64d8 Notes v3a8c64d8 Notes v3d4cbec6 Notes v246f1e57 Notes v1The quotes keep shells such as PowerShell from treating the braces specially. If you are not sure which entry you want, look first with git show 'HEAD@{2}' or git log -3 'HEAD@{2}', or create a branch on it (git branch rescue 'HEAD@{2}') instead of resetting.
Other ways to read it
- Per branch.
git reflog show featurelists moves of one branch;feature@{1}is its previous tip. After a bad rebase,git reset --hard 'feature@{1}'puts the branch back as it was before. - By time.
main@{yesterday}ormain@{2.hours.ago}resolve through the reflog to where the branch pointed then. - Rebase leaves a marker. Rebase also saves the old tip as
ORIG_HEAD, sogit reset --hard ORIG_HEADright after a rebase undoes it. - Deleted branch.
git branch -Dprints the hash it was at (Deleted branch tmp (was a8c64d8).), and HEAD's reflog lists the commits you had checked out.
Limits
- Local only. The reflog is never pushed or cloned. It shows what happened in this repository on this machine.
- It expires.
git gcprunes old entries: by default after 90 days (gc.reflogExpire), or 30 days for entries whose commits are no longer reachable from any ref (gc.reflogExpireUnreachable). After that, unreachable commits can be removed for good. - Commits only. Edits that were never committed or stashed exist only in the working tree;
reset --hardoverwrites them and nothing records them. Commit orgit stashbefore anything risky. As a last resort,git fsck --lost-foundcan find blobs you once staged withgit add.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.