Chapter 40: Git Reflog
Git reflog (also called “the reflog” or “reference log”)
This is Git’s personal undo history — a hidden, automatic diary that records every time your HEAD (current position) moved, even when you think you permanently destroyed something.
Many people only discover reflog the hard way — after doing something scary like git reset –hard and thinking “everything is gone forever”. Then someone says “check reflog” and suddenly the lost commits come back like magic.
Today I’m going to explain git reflog very clearly and slowly — like I’m sitting next to you looking at your terminal — so that you understand exactly what it is, how it works, why it’s there, when to use it, and how to stay safe.
1. What is git reflog really? (simple mental model)
reflog = Git’s private diary of where HEAD has been for the last ~90 days
Every single time your HEAD (current branch pointer) moves — no matter how — Git quietly writes a line in this diary:
- You committed → HEAD moved forward
- You reset → HEAD moved backward
- You checked out another branch → HEAD moved sideways
- You rebased → HEAD moved in complicated ways
- You pulled → HEAD moved
- Even git checkout some-old-commit (detached HEAD) → HEAD moved
Each entry gets:
- The commit hash HEAD pointed to
- A relative time (HEAD@{0} = now, HEAD@{1} = previous move, etc.)
- A short description of what action caused the move
The reflog is local only — it lives in .git/logs/HEAD and branch-specific logs. It is not pushed to GitHub. It expires after ~90 days (configurable, but default is long enough for most oops moments).
2. Why does Git even have reflog? (real reason)
Git is designed to be very hard to permanently lose data — even if you do dangerous things. The reflog is Git saying:
“I know you might panic and do something irreversible. Don’t worry — I secretly kept a breadcrumb trail of everywhere you moved HEAD. You can always go back and recover.”
Without reflog, commands like git reset –hard, git rebase, or git commit –amend would be terrifying. With reflog, they become reversible (as long as you act within ~90 days).
3. Realistic Example – See reflog in action
Create a small playground repo so you can follow along:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
mkdir git-reflog-demo cd git-reflog-demo git init echo "# Reflog Demo" > README.md git add README.md git commit -m "Initial commit" echo "- Buy milk" >> README.md git commit -am "Add first todo" echo "- Call mom" >> README.md git commit -am "Add second todo" echo "- Walk dog" >> README.md git commit -am "Add third todo" |
Now history:
|
0 1 2 3 4 5 6 7 8 9 10 |
git log --oneline # 456def7 Add third todo ← HEAD / main # abc1234 Add second todo # def5678 Add first todo # 789abcd Initial commit |
Step 1 – Do something “dangerous”
Suppose you realize you don’t want the last two commits:
|
0 1 2 3 4 5 6 |
git reset --hard HEAD~2 |
Now:
|
0 1 2 3 4 5 6 7 8 |
git log --oneline # def5678 Add first todo ← HEAD moved back # 789abcd Initial commit |
|
0 1 2 3 4 5 6 7 |
cat README.md # only shows up to "Add first todo" — the last two lines are gone! |
Panic moment: “I just lost my work!”
Step 2 – Look at reflog
|
0 1 2 3 4 5 6 |
git reflog |
Typical output (newest first):
|
0 1 2 3 4 5 6 7 8 9 10 11 |
def5678 HEAD@{0}: reset: moving to HEAD~2 abc1234 HEAD@{1}: commit: Add third todo 456def7 HEAD@{2}: commit (amend): Add second todo abc1234 HEAD@{3}: commit: Add second todo def5678 HEAD@{4}: commit: Add first todo 789abcd HEAD@{5}: commit (initial): Initial commit |
See? Even though git log no longer shows them, reflog remembers exactly where HEAD was:
- HEAD@{0} = now (after reset)
- HEAD@{1} = the commit you just threw away (Add third todo)
- HEAD@{2} = before that amend or whatever
Step 3 – Recover the lost commits
You want to go back to before the reset:
|
0 1 2 3 4 5 6 7 8 |
git reset --hard HEAD@{1} # or use the hash: # git reset --hard abc1234 |
Now:
|
0 1 2 3 4 5 6 7 8 9 10 |
git log --oneline # abc1234 Add third todo ← back! # def5678 Add second todo # 789abcd Add first todo # 123abcd Initial commit |
|
0 1 2 3 4 5 6 7 |
cat README.md # all three todos are back! |
Magic! 🎉 You recovered everything.
4. Everyday reflog commands you will use
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# See last 20 moves git reflog -20 # See only current branch reflog git reflog main # Recover a lost commit by hash git checkout -b recovered-branch abc1234 # Or hard reset back git reset --hard abc1234 # Clean up old reflog entries (rarely needed) git reflog expire --expire=now --all git gc --prune=now |
5. Very Important Safety Rules (2026 edition)
- reflog is local only — never pushed to GitHub → If you lose your laptop / delete .git folder → reflog is gone
- Entries expire — default ~90 days → Act fast if you realize you lost something months ago
- Garbage collection can remove unreachable commits → But reflog protects them for 90 days by default
- Best habit: Before any scary command (reset –hard, rebase, amend), glance at git log or git reflog first
6. Quick git reflog Cheat Sheet
| What you want to do | Command | When / Why |
|---|---|---|
| See recent HEAD movements | git reflog | First thing after any panic |
| See last 10 entries | git reflog -10 | Quick look |
| Recover lost commit to new branch | git checkout -b recovered abc1234 | Want to save it without overwriting current HEAD |
| Hard reset back to previous state | git reset –hard HEAD@{3} | After bad reset / rebase |
| See reflog for specific branch | git reflog main | When you switched branches |
| Show full reflog with dates & actions | git reflog –date=iso | Detailed investigation |
Got the reflog feeling now?
git reflog = “Git’s secret diary of everywhere HEAD has been — your personal time machine to recover from almost any mistake”
It turns dangerous commands into “eh, I’ll just check reflog if I mess up”.
Next?
- Want to practice a full “reset –hard → reflog recover” scenario?
- See reflog during interactive rebase gone wrong?
- Or wrap up with a big summary of all undo/redo commands?
Just tell me — we’ll finish strong. You’ve come incredibly far — really proud of you! 🚀
