Git Reflog: Your Last Line of Defense When Everything Goes Wrong

Git has a reputation for being unforgiving, but it quietly keeps a trail of where your branches and HEAD have been. In this article we look at git reflog as your last line of defense—how to recover from hard resets, deleted branches, and bad rebases before they turn into real disasters.

Table of Contents

Every Git user eventually has that moment.

You run a command, your working directory looks a little too clean, and your stomach drops:

  • “Wait… where did my branch go?”
  • “Why is my history different?”
  • “I just did git reset --hard… and now my work is gone.”

Most people assume they’re doomed at that point. But very often, Git has quietly kept a breadcrumb trail of where your branches and HEAD used to point.

That trail is called the reflog, and once you understand it, you can recover from a lot of “oh no” moments that would otherwise be catastrophic.

This article walks through what git reflog is, how it works, and concrete recovery scenarios you can use in real life.


What Is the Reflog?

In simple terms:

The reflog is a log of where your Git references (like HEAD and branches) have pointed over time.

Whenever you do things like:

  • git commit
  • git checkout
  • git reset
  • git rebase
  • git pull (which may create merge or rebase commits)

…Git updates HEAD (and sometimes branch refs), and records the “before” and “after” in the reflog.

You normally don’t see this data in git log because git log shows the history of the commits, not the history of where your references have pointed. The reflog is that latter piece: it’s Git’s memory of where you’ve been.

You can see it with:

Typical output looks like:

Each line is a previous position of HEAD, labeled HEAD@{N}, where {0} is the current state, {1} is one step back, and so on.

The magic: even if you “lost” a commit by resetting, rebasing, or deleting a branch, the reflog usually still knows its hash. And if you know the hash, you can almost always recover.


Scenario 1: Undoing a git reset --hard

This is the classic disaster.

You had unpushed commits on main, decided to “clean things up,” and ran:

Now your last two commits are gone.

At least, that’s how it looks.

Step 1: Check the reflog

Run:

You might see something like:

The reset itself is in the reflog (HEAD@{0}), and the commits you lost are still referenced by earlier entries (HEAD@{1}, HEAD@{2}, etc.).

Step 2: Reset back to the old commit

Let’s say e3f1c92 was the top commit before your hard reset. You can restore it with:

And just like that, your “lost” work is back.

You can also refer to reflog positions directly:

Both approaches work; using the explicit commit hash is often clearer in docs and runbooks.


Scenario 2: Recovering a Deleted Branch

Another common panic: you delete a branch and then realize it contained work that never made it into main.

Example:

Later, you realize feature/search had commits you still need.

Step 1: Find the old branch tip in the reflog

The reflog isn’t just for HEAD. Branches have their own reflogs too. You can inspect them with:

If the branch was recently deleted, you may see something like:

If Git no longer knows about that branch name at all, you can still sometimes locate the commits in the HEAD reflog (for example, from checkouts you did while working on that branch).

Step 2: Recreate the branch at the old commit

Once you’ve found the commit hash you care about (say, 9f8a7b6), recreate the branch:

Now feature/search is back, pointing to the same commit it did before deletion.

If you want to jump straight into it:


Scenario 3: Recovering from a Bad Rebase

Rebasing is powerful—and a little dangerous. It rewrites history, which is great when it works and terrifying when it doesn’t.

Say you run:

During the rebase, you hit conflicts, resolve them (maybe incorrectly), and finish. Only later do you realize something important got lost or mangled in the process.

Step 1: Inspect the reflog around the rebase

Rebases show up very clearly in the reflog:

You might see:

Often, there will be an entry like:

or a rebase (start) entry that points to your pre-rebase state.

Step 2: Reset or branch from the old commit

Once you identify the commit that represents your pre-rebase branch tip (say, 4af7e33), you have options.

  1. Completely revert to the old history:
  2. Preserve current history but also keep the old one:Create a “backup” branch from the old commit:

    Now you can compare, cherry-pick, or merge from the backup branch as needed.

Using Reflog for HEAD vs Named Branches

By default, git reflog shows the history of HEAD. But refs like branches and ORIG_HEAD also have reflogs.

Useful patterns:

If you know the approximate time of the mistake (“this was yesterday afternoon”), you can scan the reflog for entries around that timestamp.


How Long Does Reflog History Last?

The reflog isn’t forever. Git keeps it for a configurable period and then expires older entries during garbage collection.

Key settings (per-repo or global ~/.gitconfig):

  • reflogExpire — how long to keep entries for reachable commits.
  • reflogExpireUnreachable — how long to keep entries for commits that are no longer reachable from any branch/tag.

You can adjust these if you want a longer safety net, especially on critical repos:

Just remember: longer retention = more history = slightly more disk usage. For most teams, extending to 180 days is perfectly reasonable.


Reflog in Shared / Remote Repos

A few important caveats:

  • Reflog is local.
    Each clone has its own reflog. If someone else deletes a branch on the remote and you’ve never fetched or checked it out locally, your reflog can’t help.
  • Remote refs have their own reflogs (e.g., refs/remotes/origin/main), but again that history lives in your local clone.
  • Bare repos used on servers (for centralized workflows) also have reflogs, but you typically need shell access to that server to inspect them.

For disaster-recovery-style incidents, it’s often enough that some clone somewhere (CI runner, deployment box, developer laptop) still has the old commit in its reflog.


Practical Recovery Checklist

When somebody says, “I think I just lost work in Git,” here’s a concise playbook:

  1. Don’t panic, don’t run more destructive commands.
  2. Run git reflog in a local clone that has the best chance of “remembering” the old state.
  3. Identify the last known good commit:
    • Look for entries just before the destructive action (reset, rebase, branch -D, etc.).
  4. Recover by either:
    • Resetting the current branch:
    • Or creating a new branch at that commit:
  5. Push the recovered branch (if appropriate) so it’s safely stored on the remote.

Limitations: What Reflog Can’t Save You From

Reflog is powerful, but it’s not magic:

  • Once entries are expired and garbage collected, that history is gone.
  • It only helps if the commit existed in your clone at some point.
  • If you cloned after the bad change was made, your reflog won’t show the “pre-broken” history.
  • It doesn’t replace real backups or good remote hygiene (protected branches, review processes, etc.).

Think of reflog as a local time machine for your Git references. It’s a huge safety net, but not a complete disaster-recovery strategy on its own.


Conclusion: Learn git reflog Before You Need It

You don’t want your first exposure to git reflog to be in the middle of a production incident or right after nuking a week’s worth of work.

A good habit: spin up a throwaway repo and practice:

  • Make a few commits.
  • Do a git reset --hard.
  • Use git reflog to find and restore the “lost” commit.
  • Delete a branch and bring it back.

Once you’ve gone through that a couple of times, git reflog stops feeling like mysterious magic and starts feeling like just another tool in your Git toolbox—one that can quietly save the day when everything else goes wrong.

Have a project or a problem?

Talk with a senior engineer for practical recommendations—no obligation.

Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts

Categories

Get a free consultation from Reliable Penguin

Submit the form—or for immediate service call 866-649-7984.