DEV Community

Cover image for Day 3/30 - Undo Git Mistakes: The Ultimate git reflog Guide
Ruqaiya Beguwala
Ruqaiya Beguwala

Posted on • Originally published at Medium

Day 3/30 - Undo Git Mistakes: The Ultimate git reflog Guide

Git's reflog (reference logs) is one of the most powerful yet often overlooked features in Git. It's essentially Git's "safety net" that records all reference changes in your local repository.

What is Reflog?

Reflog keeps track of:

  1. Every time your HEAD pointer moves (changing branches, commits, rebases, etc.)
  2. Every time branch references are updated
  3. All these changes are recorded locally (not pushed to remote).

💡 Why This Belongs in Your Toolkit

Ever accidentally:

  • Ran git reset --hard and lost code?
  • Deleted a branch you needed?
  • Messed up a rebase/merge? git reflog is your undo button—it logs every Git action (even deletions), letting you recover almost anything.

🚀 How git reflog Works

# Show the reflog for HEAD (most common)
git reflog

# Show reflog for a specific branch
git reflog show branch-name

# Show more details (like git log)
git reflog -n 10  # last 10 entries
Enter fullscreen mode Exit fullscreen mode

Real-World Recovery Scenarios

1. Recovering Lost Commits

Scenario: You accidentally deleted a branch with important work.

🔧 Before the Operation:

* a1b2c3d (main) Update README
| * f4e5d6c (feature/login) Add login validation
| * b7e8f9a Add login form
|/
* 3829abd Initial commit
Enter fullscreen mode Exit fullscreen mode

You ran git branch -D feature/login and lost the branch.

Using reflog:

git reflog
# Output:
a1b2c3d HEAD@{0}: checkout: moving from feature/login to main
f4e5d6c HEAD@{1}: commit: Add login validation
b7e8f9a HEAD@{2}: commit: Add login form
3829abd HEAD@{3}: checkout: moving from main to feature/login
Enter fullscreen mode Exit fullscreen mode

🛠️ Recovery:

git branch feature/login f4e5d6c  # Recreate branch pointing to last commit

#Updated commit logs
* a1b2c3d (main) Update README
| * f4e5d6c (feature/login) Add login validation
| * b7e8f9a Add login form
|/
* 3829abd Initial commit
Enter fullscreen mode Exit fullscreen mode

2. Undoing a Bad Rebase

Scenario: You rebased but it caused conflicts you can't resolve.

Using reflog:

git reflog
# Output:
a1b2c3d HEAD@{0}: rebase (continue): Update README
d8e7f6a HEAD@{1}: rebase: Add OAuth support
a1b2c3d HEAD@{2}: rebase (start): checkout main
d8e7f6a HEAD@{3}: checkout: moving from main to feature/auth
Enter fullscreen mode Exit fullscreen mode

🛠️ Recovery:

git reset --hard HEAD@{3}  # Back to state before rebase started
#OR
git reset --hard d8e7f6a
Enter fullscreen mode Exit fullscreen mode

3. Finding Lost Work After Hard Reset

Scenario: You did a hard reset and lost recent commits.

🔧 Before the Operation:

* e9f8g7h (HEAD -> main) Add new API endpoint
* d8e7f6a Update config
* a1b2c3d Update README
* 3829abd Initial commit
Enter fullscreen mode Exit fullscreen mode

You ran git reset --hard a1b2c3d and lost the top two commits.
✅ Using reflog:

git reflog
# Output:
a1b2c3d HEAD@{0}: reset: moving to a1b2c3d
e9f8g7h HEAD@{1}: commit: Add new API endpoint
d8e7f6a HEAD@{2}: commit: Update config
a1b2c3d HEAD@{3}: checkout: moving from feature to main
Enter fullscreen mode Exit fullscreen mode

🛠️ Recovery:

git checkout e9f8g7h  # Checkout the lost commit
git branch recovered-branch  # Create new branch for it
Enter fullscreen mode Exit fullscreen mode
* e9f8g7h (recovered-branch) Add new API endpoint
* d8e7f6a Update config
| * a1b2c3d (main) Update README
|/
* 3829abd Initial commit
Enter fullscreen mode Exit fullscreen mode

4. Recovering Deleted Branches

Scenario: You deleted a branch that wasn't merged.

🔧 Before the Operation:

* f4e5d6c (HEAD -> main) Update CI config
| * g3h2i1j (feature/payments) Add payment processing
| * b7e8f9a Add payment form
|/
* 3829abd Initial commit
Enter fullscreen mode Exit fullscreen mode

You ran git branch -D feature/payments.
Using reflog:

git reflog --all | grep payments
# Output:
g3h2i1j refs/heads/feature/payments: commit: Add payment processing
b7e8f9a refs/heads/feature/payments: commit: Add payment form
Enter fullscreen mode Exit fullscreen mode

🛠️ Recovery:

git branch feature/payments g3h2i1j

#Commit history
* f4e5d6c (HEAD -> main) Update CI config
| * g3h2i1j (feature/payments) Add payment processing
| * b7e8f9a Add payment form
|/
* 3829abd Initial commit
Enter fullscreen mode Exit fullscreen mode

🔑 Pro Tips

1. Time-based References

Find what your branch looked like 2 hours ago

# See what HEAD looked like at specific times
git show HEAD@{2.hours.ago}

# Checkout main branch as it was yesterday
git checkout main@{yesterday}

# See what changes were made in the last 30 minutes
git diff HEAD@{30.minutes.ago} HEAD
Enter fullscreen mode Exit fullscreen mode

2. Configuring Reflog Expiration

Change default 90-day expiration to 180 days

# Set global expiration
git config --global gc.reflogExpire 180.days
git config --global gc.reflogExpireUnreachable 180.days

# Verify settings
git config --get gc.reflogExpire
Enter fullscreen mode Exit fullscreen mode

3. Combining with Bisect

Find when a bug was introduced using reflog

# Start bisect session
git bisect start
git bisect bad HEAD

# Use reflog to find a known good commit from 2 weeks ago
git bisect good main@{2.weeks.ago}

# After finding the bad commit, check reflog to see what happened
git reflog | grep -A 5 <bad-commit-hash>

Enter fullscreen mode Exit fullscreen mode

4. Detailed Reflog View

Compare regular vs detailed reflog

# Regular reflog
git reflog -n 3
# Output:
# f4e5d6c HEAD@{0}: commit: Update API docs
# a1b2c3d HEAD@{1}: pull origin main
# 3829abd HEAD@{2}: checkout: moving from feature to main

# Detailed view (like git log)
git log -g -n 3 --pretty=fuller
# Output shows full commit metadata:
# commit f4e5d6c
# Author:     Your Name <you@example.com>
# AuthorDate: Tue Oct 10 14:30:00 2023 +0200
# Commit:     Your Name <you@example.com>
# CommitDate: Tue Oct 10 14:30:00 2023 +0200
#
#     Update API docs
Enter fullscreen mode Exit fullscreen mode

5. Creating Safety Nets

Create a tag before a dangerous operation.

git tag SAFETY_NET  # Creates a permanent reference
git reset --hard HEAD~3  # Dangerous operation
git checkout SAFETY_NET  # If things go wrong, Go back to the tagged state
Enter fullscreen mode Exit fullscreen mode

6. Colorful Reflog Alias in Action

Using the pretty-printed reflog alias

# First create the alias (if you haven't already)
git config --global alias.lg "log -g --pretty='%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'"

# Now use it
git lg -n 3
Enter fullscreen mode Exit fullscreen mode

7. Undo your last move

Using alias for going back to the last change

[alias]
  undo = !git reset --hard $(git reflog | awk '/HEAD@{/ {print $1}' | head -1)
Enter fullscreen mode Exit fullscreen mode

8. Bonus Trick: Finding Lost Stashes

Recover a dropped stash

# Find all stash operations in reflog
git reflog | grep -i 'stash'

# Output might show:
# 3829abd HEAD@{15}: stash pop
# a1b2c3d HEAD@{22}: stash

# Recover a specific stash
git stash apply HEAD@{22}
Enter fullscreen mode Exit fullscreen mode

🔁 To remember

  1. Check reflog immediately when something goes wrong
  2. Look for the last known good state
  3. Use the HEAD@{n} references or commit hashes to recover
  4. Create aliases to make reflog more user-friendly

Up Next: Day 4: git bisect – Binary search to find the commit that introduced a bug.


Daily advance GIT tips in your inbox—worth starting? Respond to my poll here🚀
For more useful and innovative tips and tricks, Let's connect on Medium

Top comments (0)