[Advanced Git] Git reflog: Recovering commit history and every action in Git

VnnTools

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.

Git reflog: Recovering commit history and every action in Git

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 you push.
  • 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!

  1. Open the "diary": Run git reflog.

  2. 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.

  3. 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:

  1. Run git reflog.

  2. 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.

  3. 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.

  1. Run git reflog.

  2. Look for the line that says rebase: checkout ORIG_HEAD or similar. The position right before that is where you started.

  3. 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! 🚀

Related Posts

[Advanced Git] Git Reset or Git Revert? Choose the Right Way to Undo

No more confusion between git reset and git revert! This guide will help you understand how each command works, so you can choose the right tool to undo changes in Git like a pro.

[Advanced Git] Git Rebase Guide: Understand and Use Effectively

Git Rebase is used to rearrange, combine, and modify commits. This article helps you distinguish Git Rebase from Git Merge, and master how to use Git Rebase effectively and safely.

[Git Basics] How to Use Git log: Mastering Commit History

Want to review your project’s change history? A detailed guide to using git log from basic to advanced, helping you manage commits more efficiently and easily.

[Git Basics] What is a Git Branch? Mastering Branches in Git

Branching is a crucial feature that helps split projects in Git. Read this article to understand Git Branch, how to create, delete, and switch between branches easily.