How to Rescue Your Commits with Git Reflog

Intro

The Git version control system can be quite intimidating, especially for beginner and intermediate users. Its commands can feel obscure and when mistakes happen, like accidentally deleting a branch or overwriting commits, it can seem like there’s no way to recover.

But here’s the good news: Git has a hidden safety net called reflog, and it can rescue you from even the trickiest situations.

In this video, I’ll show you how git reflog works and walk you through some practical examples where it can save your work and help you recover from common Git mistakes. Whether you’re a solo developer or working in a team, understanding reflog can give you the confidence to handle Git like a pro!

If you enjoy this video and want to dive deeper into Git and other interesting topics, check out the links in the description for more resources, like my upcoming Git Good workshop, where we’ll cover real-world Git techniques step by step.

Now let’s learn a bit about git reflog!

What is Git Reflog?

git reflog is a command that gives you access to a log of previous Git operations. The reflog command is like a time machine view into your Git workflow: it effectively gives you the history of everything that has changed HEAD, a special name that points to the commit that represents the current state of your local repository.

Let’s run git reflog now to see what it tells us about the current state of a brand new repository I just created:

git reflog

The reflog command can tell you about a variety of Git operations that you might have performed on your local repo and any “remotes” where you collaborate with others. It even tracks changes that may not appear in the typical commit history!

Here are some examples:

  • Creating commits
  • Switching branches
  • Resetting branches
  • Amending commits
  • Merges and rebases
  • Cherry-picks across branches
  • Reverting a commit
  • Stashing changes
  • Pulls and fetches
  • Force pushes

Reversing many of these changes will require knowledge of other Git commands, but reflog gives you the information you need to fix a variety of common mistakes we all make when working with Git repositories!

Let’s jump into a brief tour of a few real-world scenarios where reflog can save you from despair when working on important projects.

Recovering a Deleted Branch

Have you ever deleted the wrong branch by accident? This can be a pretty stressful situation if you haven’t pushed your changes to a remote repository.

Fortunately, Git’s reflog can be your safety net, allowing you to recover what appear to be lost commits and get back on track with minimal hassle.

Let’s try doing the most extreme version of this: deleting the master branch of our repository!

git branch -D master
git branch -v

Oh no, what do we do? Well, let’s see what Git reflog tells us:

git reflog

We can see that there is a log entry for a commit that moved the hash to 7a92a56. To get our master branch back, we can use git checkout -b to create a new master branch with the commit hash of the most recent commit:

git checkout -b master 7a92a56
git status

Now our master branch is exactly where it was before! The key here was that git reflog helped us find the hash of the commit to which the branch named master previously pointed.

Understanding Git Branches

Why does this work? Doesn’t deleting a branch delete the commits that are associated with it?

Not quite! In Git, a branch is simply a label that refers to a specific commit in the repository. When you create a branch, you’re essentially giving a name to a particular commit, and as you make new commits on that branch, the pointer moves forward to the latest commit.

Deleting a branch only removes that label, it doesn’t delete the associated commits. As long as no other branch or reference points to those commits, Git still keeps them around temporarily.

So, while the branch name might disappear, the underlying commits are still accessible through git reflog, at least until Git eventually cleans them up during its garbage collection process.

Recovering “Detached HEAD” commits

Have you ever seen git status tell you that you have a “detached head”? This is not some Ichabod Crane type of situation, it basically just tells you that your working directory is not associated with a branch.

The surprising thing is that even without a branch, you can still make commits and move HEAD! This is exactly the state that my working directory is in right now after mistakenly using git checkout instead of git reset to roll back to a previous commit.

In this case git checkout moves HEAD to the desired commit without moving the branch you’re currently in! If I create a new commit now, it won’t be associated with any branch because we’re still in a detached HEAD state:

git status

So what happens if I then switch to another existing branch without first creating a branch that refers to the current state of HEAD?

git checkout master

Luckily git will try to warn me about this with a helpful message:

Warning: you are leaving 1 commit behind, not connected to
any of your branches:

  b96095e Headless

If you want to keep it by creating a new branch, this may be a good time
to do so with:

 git branch <new-branch-name> b96095e

But let’s assume that you didn’t read this message for some reason. How could you get back to the previous commit?

We can use git reflog to see the moment where we checked out the master branch, including the commit hash that we created while HEAD was detached:

git reflog --all

We can see the reflog entry for the commit that was added on top of the checkout that moved HEAD, so we can easily create a new branch for that commit by using git branch:

git branch ichabod b96095e

Recovering From a Rebase Mistake

If you’ve been using Git for a while, you might have become familiar with git rebase. It’s a super powerful tool for editing the commit history of a branch so that you can reorder commits, merge them together, change their wording, drop other commits, and much more.

You can basically do all these things in a single rebase operation without running a ton of git commands!

In this example, I’ve just run a rebase that reworded the first commit, merged another commit into it, and dropped the last commit. Let’s assume that once the rebase was done, I realized that I didn’t actually want to drop that commit! How can git reflog help here?

It can help us find the commit we created just before we attempted the botched rebase operation:

git reflog

Now that we know the hash of the last commit that was created before we attempted the rebase, we can use git reset to move the current branch back to that commit:

git reset --hard <commit-hash>

Now we can attempt the rebase again without dropping that commit!

An Alternative Approach

Another approach would be to find the hash of the dropped commit either using git reflog or using git log on a remote branch you might have already pushed and then use git cherry-pick to apply that commit on top of your newly rebased commit(s).

Let’s assume that we’ve already completed the rebase at this point and we’re able to find the hash of the commit we want to recover:

git cherry-pick <commit-hash>

Understanding how Git works will give us a number of options on how to fix problems like this with the help of the information we get from git reflog and git log.

Conclusion

As you can see, git reflog can rescue you from many common Git mistakes. It will also make you seem like a super hacker when someone comes to you sweating about lost work and begging for help. Now you can save their dignity and be a hero with git reflog!

Hope you found that useful, and until next time, happy hacking!

Subscribe to the System Crafters Newsletter!
Stay up to date with the latest System Crafters news and updates! Read the Newsletter page for more information.
Name (optional)
Email Address