Git Reflog: Recovering Lost Commits and Fixing Mistakes


Losing commits or branches due to Git operations like reset
, rebase
, or branch deletion can be frustrating. Fortunately, Git maintains a detailed log of reference changes called the reflog, which serves as a safety net for recovering lost work.
This article explains:
How the reflog works
Practical scenarios for recovering commits
Limitations of the reflog
Understanding the Reflog
The reference log (reflog) records all changes to Git references (branches, HEAD) in your local repository. Unlike the commit history, which is shared across clones, the reflog is local and temporary (typically retained for 90 days).
Key properties:
Tracks every
commit
,checkout
,merge
,rebase
, andreset
operationEach entry includes a commit hash, action, and timestamp
Accessed via
git reflog
or inspecting.git/logs/
Common Recovery Scenarios
1. Restoring After a Hard Reset
If you ran:
git reset --hard HEAD~1 # Discards the last commit
Recovery steps:
Identify the lost commit:
git reflog
Example output:
a1b2c3d HEAD@{0}: reset: moving to HEAD~1 e4f5g6h HEAD@{1}: commit: Implement user authentication
Restore the commit to a new branch:
git checkout -b recovered-branch e4f5g6h
2. Recovering a Deleted Branch
After deleting a branch:
git branch -D feature/login
Recovery steps:
Locate the branch's final commit:
git reflog --all | grep 'feature/login'
Recreate the branch:
git branch feature/login e4f5g6h
3. Fixing a Failed Rebase or Merge
If a rebase introduced conflicts or errors:
Find the pre-rebase state:
git reflog
Reset to the stable commit:
git reset --hard HEAD@{2}
Technical Notes
How the Reflog Works
Entries are stored in
.git/logs/HEAD
and.git/logs/refs/heads/<branch>
HEAD@{n}
syntax refers to the nth prior position of HEADTimestamps use the format
HEAD@{5.minutes.ago}
Limitations
Local only: Not shared via
push
/pull
Temporal: Entries expire (~90 days by default)
No unstaged changes: Only tracks committed states
Best Practices
Verify before destructive operations
Use--dry-run
withreset
orprune
to preview changes.Document important hashes
Note commit hashes before complex operations like interactive rebases.Combine with
fsck
for orphaned commitsgit fsck --lost-found
Reference Commands
Command | Purpose |
git reflog | Show all reference changes |
git reflog show <branch> | View branch-specific history |
git checkout HEAD@{n} | Restore HEAD to a prior state |
git reset --hard <hash> | Discard changes to a specific commit |
Conclusion
The reflog is an essential tool for recovering from Git mishaps. By understanding how to:
Locate lost commits
Restore deleted branches
Revert failed operations
developers can work with confidence, knowing mistakes are recoverable. For team workflows, consider supplementing with remote backups or tags for critical commits.
Subscribe to my newsletter
Read articles from Emil Rustamzade directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
