Table of Contents
Managing branches or commits in Git can be quite cumbersome. Issues ranging from merge conflicts to accidentally deleting branches are a nightmare for many developers. It could get even worse if you are working with a bunch of other developers, as it’s easy to modify or even completely remove another person’s work, whether knowingly or inadvertently.
In this tutorial, you will learn how to recover your deleted commits or branches using the `git reflog`
command. This command is used to get a record of references to the tips of branches and commits that have been updated. Per the official `git`
documentation,
“Reference logs, or “reflogs,” record when the tips of branches and other references were updated in the local repository. Reflogs are useful in various Git commands, to specify the old value of a reference.”
Before diving further into the `git reflog`
command, let’s take a look at some basics of Git.
`HEAD
` in Git
`HEAD
` is primarily a reference to a named branch in a Git repository. It is like a pointer that points to a branch, and that branch itself points to a particular commit. Thus, the `HEAD
` pointer indirectly points to a particular commit.
However, it can also point directly to a commit. This state is known as detached HEAD state. To better understand this, consider an example:
Image courtesy of Learning Git Branching
In the image above, the HEAD is pointing to the main branch and the main branch is pointing to the C1 commit.
Image courtesy of Learning Git Branching
Here, the HEAD is not referencing or pointing to the main branch; instead, it is pointing directly to the C1 commit. This can be achieved using the `git checkout`
command.
Now, let’s make a new commit.
Image courtesy of Learning Git Branching
As you can see, when the new commit was created, the HEAD pointer changed its reference and now points toward the latest commit, C2. However, the main branch still points toward the C1 commit. This is known as a detached HEAD state.
You can also use `HEAD
` to create a new branch by referencing a particular commit. For example:
Image courtesy of Learning Git Branching
This is your main branch. Let’s say that you want to create a new branch from commit C1. To do so, you must point the HEAD to the desired commit. There are a few ways to do this. One option is to point the HEAD directly to the C1 commit by specifying its SHA value. Alternatively, you can also make the HEAD point toward that commit by using the current position of the HEAD itself.
You can achieve this by using either of these commands:
`git checkout HEAD^^
` or `git checkout HEAD~2
`.
Image courtesy of Learning Git Branching
In the example, HEAD now points to the C1 commit. To create a new branch, simply execute the command `git branch <branch_name>`
. Then, point the HEAD to the new branch using `git checkout <new_branch_name>
`. The commits that you will make after this will be updated in the new branch.
Image courtesy of Learning Git Branching
Now that you have a basic understanding of these concepts in Git, let’s take a closer look at the `git reflog
` command and see how you can use it to recover deleted branches or commits.
Using `git reflog`
to Recover Deleted Branches
As mentioned previously, reference logs, otherwise known as “reflogs,” are used to record when updates are made in the local repository to the tips of branches and commits.
In other words, using `git reflog`
, you can get information about the HEAD pointer and the various commits to which it pointed in the past or present
Let’s say that you have a main branch and then created a new branch named b1 using the command `git branch b1`
. Then you accidentally deleted this branch using `git branch -D b1`
. At this point, either you immediately realize the mistake (for example, deleting another branch instead of the intended one) and it was the last step you performed in your terminal, or you don’t even realize initially that you deleted the wrong branch but later you realize it.
In the first case, you can simply check the message in the terminal after the deletion of the branch. It may look something like this:
In the above message, you can see the SHA value of the commit to which the branch pointed when it was deleted.
Next, execute the `git checkout <sha value>`
command. This command will point the HEAD to the commit of which the SHA value has been specified. This will create a detached HEAD state, which was discussed earlier.
After this, execute the `git checkout -b <branch_name>`
command. This will create a new branch from that commit itself, and the HEAD pointer will point to the branch.
In the second case, if you’ve lost the message, you can use `git reflog`
to find the SHA of the commit that was at the tip of the deleted branch. Be sure to name your commits properly so that you can find them easily.
Then, to proceed, you may perform the same commands as detailed in the first case above.
Using `git reflog`
to Recover Deleted Commits
The process for recovering a deleted commit is quite simple. All that is necessary is to use `git reflog`
to find the SHA value of the commit that you want to go to, and then execute the `git reset --hard <sha value>`
command. Remember that this command will delete all your working directory changes that are not yet committed, so be sure to use it carefully.
Drawbacks of `git reflog`
While `git reflog`
can be particularly useful for restoring deleted branches and commits, it also has some drawbacks. Most notably, reference logs are stored locally, so you can’t really push or pull them from a remote repository. Also, they typically expire or are erased after a certain amount of time to save disk space.
In order to overcome these drawbacks, you can opt for a backup solution like BackHub by Rewind. With BackHub, you can automatically back up your repositories and crucial metadata (pull requests, issues, projects, etc.) on a daily basis. You can also restore your data using the GitHub API almost instantly. To get started, set up a free trial of BackHub or reach out to sales@rewind.com to schedule a demo and learn more.