Every developer working with Git has probably experienced that "heart-stopping" moment 😱: accidentally deleting an important branch, running reset --hard
on a cherished commit, or performing a disastrous rebase
. In those moments, you wish you had a time machine to go back? The good news is, Git already provides you with such a "machine", and it's called Git Reflog.
This article will help you understand "What is Git Reflog", why it is a lifesaver for every developer, and how to use it most effectively.
Git Reflog: "The secret diary" of HEAD 📝
To make it easier to imagine, think of git log
as the official chronicle of your project, recording important milestones (commits) that have been shared with everyone. It's public, sequential, and part of the shared history.
In contrast, git reflog
(short for "reference log") is like your personal diary. It doesn't care about the "official" project history, but quietly records every action that changes the position of the HEAD pointer on your local machine. Whenever you commit
, checkout
, reset
, merge
, rebase
, or run any command that moves HEAD, reflog
logs a line: "I was here, and now I've moved there".
This is the key difference:
git log
: Records the history of commits in the project. This history is shared when youpush
.git reflog
: Records the movement history of HEAD only on your machine. It's local and not pushed to the remote repository.
Because of its "personal" and "records everything" nature, reflog
becomes an invaluable safety net. Even if a commit is no longer referenced by any branch or tag (often called an "orphaned" or "lost" commit), it still exists in the reflog.
Why is Reflog a developer's "magic tool"? 🦸♂️
The real power of git reflog
lies in its ability to recover things you thought were lost. Here are some "nightmare" scenarios where reflog can save you.
Scenario 1: Accidentally deleted a branch
You're cleaning up old branches and accidentally run git branch -D feature-week-long-work
. All your week's effort seems to vanish. Don't panic!
-
Open the "diary": Run
git reflog
. -
Find the trace: You'll see a list of recent actions. Look for the line right before you checked out of the deleted branch. It will look like
checkout: moving from feature-week-long-work to main
. -
Revive the branch: Copy the commit hash (e.g.,
a1b2c3d
) and magically recreate the branch:git checkout -b feature-week-long-work a1b2c3d
Voilà! Your branch is back as if nothing happened.
Scenario 2: "Reset --hard" gone wrong 😭
This is probably the most classic situation. You want to go back a few commits and confidently type git reset --hard HEAD~3
. After doing so, you realize you've deleted 3 very important commits. git log
no longer shows them.
Once again, git reflog
comes to the rescue:
-
Run
git reflog
. -
You'll see the history of HEAD positions. The commits you just "threw away" will be at the top of the list, usually marked as
HEAD@{1}
,HEAD@{2}
, etc. -
Turn back time: Suppose the last commit you want to recover has the hash
e4f5g6h
(HEAD@{1}
). Reset back to that state:git reset --hard e4f5g6h
All your code is safely restored.
Scenario 3: Rebase "disaster"
You perform a complex rebase
and end up with a messy commit history and conflicts everywhere. You just want to return to the "safe" state before the rebase.
reflog
has recorded the starting point of the rebase.
-
Run
git reflog
. -
Look for the line that says
rebase: checkout ORIG_HEAD
or similar. The position right before that is where you started. -
Copy the commit hash and return to it:
git reset --hard <commit-hash-before-rebase>
How to use Git Reflog effectively
The most basic command is git reflog
or git reflog show
. The output looks like:
a1b2c3d HEAD@{0}: commit: Add payment feature
e4f5g6h HEAD@{1}: reset: moving to HEAD~3
f0g9h8i HEAD@{2}: commit: UI optimization
...
Explanation of the components:
a1b2c3d
: The commit hash (SHA-1).HEAD@{0}
: This is the reflog pointer.HEAD@{0}
is the most recent position of HEAD (i.e., now),HEAD@{1}
is the previous position,HEAD@{2}
is before that, etc.commit: Add payment feature
: The action that moved HEAD and the commit message.
You can use these pointers directly in other Git commands:
# Checkout the state of HEAD 2 steps ago
git checkout HEAD@{2}
# Compare the difference between the current state and 5 steps ago
git diff HEAD@{5} HEAD@{0}
# Cherry-pick a commit from the reflog into the current branch
git cherry-pick a1b2c3d
Important note: Reflog does not last forever!
reflog
is a cleanup mechanism. By default, entries in the reflog are automatically deleted after 90 days. This means you can't use it to recover changes from too long ago. This period can be configured, but 90 days is usually enough for most "emergency" cases.
Conclusion: Treat Reflog as your companion
Even though git reflog
isn't a command you use every day, in tough times, it's your most reliable companion. It gives you the confidence to experiment, to make mistakes, and to know that there's always a way back.
Make it a habit: when you run into trouble, before panicking, calmly type git reflog
and review your "diary". The solution to your problem is likely right there in the first few log lines. Happy coding, and may you never "lose" a commit again! 🚀