¶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!