Back to Blog

What Nobody Tells You About Using Git Reflog to Reverse Your Worst Command Line Disasters

What Nobody Tells You About Using Git Reflog to Reverse Your Worst Command Line Disasters

What Nobody Tells You About Using Git Reflog to Reverse Your Worst Command Line Disasters

I remember the first time I ran git reset --hard on the wrong branch. I felt a cold sweat prickle my neck as the terminal returned a silent, successful prompt. I’d just wiped out three hours of logic that I hadn't pushed to origin yet. For years, I thought that was it—the bits were gone, scattered into the void of my SSD. But Git is a hoarder. It’s nearly impossible to actually lose work in Git if you committed it at least once, thanks to a hidden ledger called the reflog.

Most people think of git log as the history of their project. It isn't. git log is the history of the *commits*. git reflog, however, is the history of your *actions*. It’s a diary of everywhere your HEAD has pointed for the last few months.

The "Oh No" Moment: A Practical Example

Let’s say you’re deep in a messy rebase. You’ve got conflicts, you’re tired, and you accidentally run git rebase --abort when you meant to continue, or worse, you finish the rebase and realize you squashed three commits you actually needed to keep separate.

Standard git log won't help you here. The old commits are no longer part of your branch's lineage. This is where you pull the ripcord:

git reflog

You’ll see a list that looks something like this:

4f2a1b3 HEAD@{0}: rebase (finish): returning to refs/heads/feature-xyz
4f2a1b3 HEAD@{1}: rebase (pick): Add user authentication
a9c8d7e HEAD@{2}: rebase (pick): Fix bug in login flow
7b6e5d4 HEAD@{3}: rebase (start): checkout main
92d1c3a HEAD@{4}: commit: WIP: work before rebase

The magic is in that HEAD@{n} syntax. HEAD@{0} is where you are now. HEAD@{4} is where you were five actions ago—right before you started that disastrous rebase.

How to Actually Resurrect Your Code

Once you find the "good" state in the reflog, you have two main ways to fix your life.

1. The "I'm 100% Sure" Reset

If you want to move your current branch back to that exact moment in time (say, HEAD@{4}), just run:

git reset --hard HEAD@{4}

Warning: This is destructive to your current uncommitted working directory. If you have unsaved changes, stash them first.

2. The "I'm Scared to Break It Further" Branch

If you’re worried about making things worse, don't reset. Just create a new branch from that specific moment in the reflog:

git checkout -b rescue-mission HEAD@{4}

Now you have a new branch that contains your code exactly as it was before the disaster. You can cherry-pick from it or just swap over to it and delete the broken one.

The Secret "Checkout" Trick

Sometimes you don't lose a whole branch; you just mess up one specific file during a merge or rebase. You can use the reflog to pull a single file from the "ghost" of a previous state:

git checkout HEAD@{12} -- path/to/your/file.js

This reaches into the reflog, finds the state of the repo 12 actions ago, and grabs just that one file. It’s surgical and incredibly satisfying.

The Fine Print (The "Gotchas")

There are two things nobody tells you until it's too late:

1. The Clock is Ticking: Git eventually cleans up "unreachable" commits (those not tied to a branch or tag). By default, reflog entries are kept for 90 days, but if the commit is unreachable, it might be pruned in as little as 30 days. It’s not an infinite backup.
2. It’s Local Only: The reflog is a local record of *your* movements. If you delete your local folder and re-clone, your reflog is gone. You cannot see your coworker’s reflog, and they cannot see yours. It is your personal safety net, not a team-wide undo button.

Why This Matters

Git’s greatest strength isn't that it tracks history; it’s that it’s designed to be nearly impossible to break. When you realize that HEAD is just a pointer and the reflog is just a list of where that pointer has been, the "magic" of the command line disappears and is replaced by a tool you can actually control.

The next time you botch a rebase or lose a commit in a hard reset, don't panic. Just check the ledger. Your code is probably still there, waiting for you to find its hash.