Stage 2 · Tools
Git Internals & Advanced
git reflog
Recover lost commits and understand Git's safety net for every operation.
What is reflog
The reflog (reference log) is Git's internal journal that records every change to HEAD and branch references. Every time you commit, switch branches, merge, rebase, reset, or stash, Git records the previous state in the reflog. It is a local-only mechanism, never shared with remote repositories, and serves as your ultimate safety net for recovering from mistakes.
Unlike the commit history which is immutable and shared, the reflog is a mutable, local log. Each entry has a sequential index and a timestamp. The reflog retains entries for a configurable period, typically 90 days for reachable commits and 30 days for unreachable ones.
Viewing reflog entries
The git reflog command shows the history of HEAD changes. Each entry displays the commit hash, the operation that created it, and the relative timestamp. The HEAD@{n} syntax references a specific reflog entry where n is the number of steps back.
git reflogShows the history of HEAD changes with commit hashes and operation descriptions.
git reflog show mainShows the reflog for the main branch, recording all changes to the main branch reference.
The output shows entries like a1b2c3d HEAD@{0}: commit: Add login feature. The HEAD@{0} notation means this is the most recent change to HEAD. HEAD@{1} is the previous state, HEAD@{2} is two steps back, and so on. You can use these references in most Git commands.
Recovering lost commits
When you accidentally reset to a wrong commit or lose work after a rebase, the reflog lets you recover. The lost commit still exists in Git's object database and the reflog records the hash. You can checkout the commit, create a new branch at it, or reset your current branch back to it.
# You accidentally reset to the wrong commit
git reset --hard HEAD~3
# View the reflog to find the lost commit
git reflog
# a1b2c3d HEAD@{0}: reset: moving to HEAD~3
e4f5g6h HEAD@{1}: commit: Implement search feature
# Option 1: Checkout the lost commit
git checkout e4f5g6h
# Option 2: Reset your branch back to it
ngit reset --hard e4f5g6h
# Option 3: Create a new branch to preserve it
git branch recovered-branch e4f5g6hThree ways to recover a lost commit using reflog entries.
HEAD@{0} is always the most recent state. Use HEAD@{1} for the previous state, or reference by date with HEAD@{2.hours.ago}. The reflog index resets when you run git reflog expire.
Recovering a dropped stash
When you drop a stash with git stash drop, the reflog still records the stash entry. The stash reflog is separate from the HEAD reflog and is accessible via the stash reflog. You can recover a dropped stash by finding its commit hash in the stash reflog and applying it.
# Drop a stash
git stash drop stash@{0}
# View stash reflog to find the dropped stash
git reflog show stash
# a1b2c3d stash@{0}: On main: WIP on main
e4f5g6h stash@{1}: On main: WIP on main
# Apply the dropped stash
git stash apply e4f5g6h
# Or create a branch from the stash state
git branch recovered-stash e4f5g6hRecover a dropped stash by finding it in the stash reflog and applying or branching from it.
Reflog expiration and cleanup
Reflog entries are not permanent. Git automatically expires old entries to reclaim space. By default, reachable entries are retained for 90 days and unreachable entries for 30 days. You can manually expire entries with git reflog expire or force garbage collection to prune unreachable objects.
# Expire all reflog entries now
git reflog expire --expire=now --all
# Aggressive garbage collection
git gc --prune=now --aggressive
# Check repository size before and after
du -sh .gitForce expiration of reflog entries and aggressive garbage collection to reclaim disk space.
Once reflog entries are expired and garbage collection runs, the associated objects are permanently deleted. Only run aggressive gc when you are certain you do not need to recover old commits.
Reflog as your safety net
The reflog is your safety net for every Git operation. Every destructive action, every reset, every rebase, and every stash drop leaves a trail in the reflog. As long as the reflog entries have not expired, you can recover from virtually any Git mistake. This is why experienced Git users are rarely afraid of making mistakes.
- git reset --hard loses commits, but the reflog remembers them
- git rebase --onto can drop commits, but they appear in reflog
- git stash drop removes stashes, but they stay in stash reflog
- git commit --amend rewrites commits, the old commit is in reflog
- git checkout -- discard changes, the previous state is in reflog
The reflog is local to your machine and never pushed to a remote. It is a personal safety net that works independently of what your collaborators see. This makes it safe to experiment without fear.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.