The Hook (The "Byte-Sized" Intro)
Every time HEAD moves — commit, reset, rebase, checkout, merge — Git writes a line in the reflog. It's a flight recorder for your repo. Even after a git reset --hard, the "lost" commits still exist. git reflog shows you where HEAD has been, and git reset --hard <sha> takes you right back. It's the ultimate undo button for the undo button.
📖 What is Recovering with Reflog?
The reflog (reference log) is a local record of every position HEAD has pointed to. It includes commits, resets, rebases, checkouts, and merges. You can use it to find and restore commits that are no longer reachable from any branch.
Conceptual Clarity
Reflog output:
abc1234 HEAD@{0}: reset: moving to HEAD~3
def5678 HEAD@{1}: commit: Add payment feature
ghi9012 HEAD@{2}: commit: Add user dashboard
jkl3456 HEAD@{3}: checkout: moving from feature to main
| Column | Meaning |
|---|---|
abc1234 | The SHA at that point in time |
HEAD@{0} | How many operations ago (0 = current) |
| Action | What caused HEAD to move |
Key facts:
- Reflog is local only — not shared with teammates or pushed to remote
- Entries expire after ~90 days (configurable via
gc.reflogExpire) - Works for branch refs too:
git reflog show feature/login
Real-Life Analogy
Reflog is like the "Recently Closed Tabs" feature in your browser. You might close a tab accidentally, but the browser remembers where you were. git reflog remembers where HEAD was, even after destructive operations.
Visual Architecture
Why It Matters
- Safety net: Reflog makes almost every Git mistake recoverable.
- Rebase recovery: Reflog shows your branch's pre-rebase position.
- Reset recovery: Even
git reset --hardleaves reflog entries. - Confidence: Knowing reflog exists lets you experiment without fear.
Code
# ─── View the reflog ───
git reflog
# Shows: SHA HEAD@{N} action description
# ─── Recover after accidental reset ───
git reflog
# Find the commit before the reset:
# def5678 HEAD@{1}: commit: Add payment feature
git reset --hard def5678
# You're back!
# ─── Recover after bad rebase ───
git reflog
# Find: abc1234 HEAD@{5}: rebase (start): checkout main
# The entry BEFORE that is your pre-rebase state
git reset --hard HEAD@{6}
# ─── Create a rescue branch instead of resetting ───
git branch rescue-branch def5678
git switch rescue-branch
# ─── View reflog for a specific branch ───
git reflog show feature/login
# ─── Reflog with timestamps ───
git reflog --date=relative
# Shows: HEAD@{2 hours ago}: commit: Add featureKey Takeaways
- Reflog records every HEAD movement — commits, resets, rebases, checkouts.
- Use
git reflog+git reset --hard <sha>to undo almost any mistake. - Reflog is local only and expires after ~90 days.
- Creating a rescue branch is safer than resetting when you're unsure.
Interview Prep
-
Q: What is the reflog and how does it help with recovery? A: The reflog is a local log of every position HEAD has pointed to. It tracks commits, resets, rebases, and other operations. When commits become unreachable (e.g., after a hard reset), reflog lets you find their SHA and restore them.
-
Q: Is the reflog shared with other developers? A: No. The reflog is strictly local to your repository. It's not pushed to remotes or included in clones. Each developer has their own reflog reflecting their local operations.
-
Q: How long do reflog entries last? A: By default, reflog entries for reachable commits expire after 90 days, and entries for unreachable commits expire after 30 days. These are controlled by
gc.reflogExpireandgc.reflogExpireUnreachablesettings.