A Detached HEAD in Git: What it is And How to Fix it

Brian Bojan Dordevic
About The Author

Brian Dordevic

Brian is Marketing Strategic Planner with a passion for all things digital. Feel free to follow him on Twitter or schedule a consultation call with him.

With its complex commands and not-so-intuitive user interface, Git has a very steep learning curve. While trying to master this version control system, you may encounter some perplexing scenarios and unwanted states such as Git detached HEAD. Though the message You are in a detached HEAD state may sound somewhat strange to newcomers, it is a perfectly valid state of the Git repository and recovering from it is not that difficult.

In today’s article, our web development agency in Chicago explores the meaning of detached HEAD in Git and various situations that can cause this state. We will also demonstrate ways to recover from this situation rapidly.

What is HEAD in Git?

The term HEAD in Git refers to the latest commit of your currently checked-out branch. A Git repository is composed of different objects and references. While objects are in various relations, references point to objects or other references. Commits are the most important objects in a Git repository. Other objects include blobs and trees. 

On the other hand, the main references in Git are branches. HEAD is also an essential type of reference that tracks the current point in a Git repository and tells you where you are. For example, when you use the git log command, HEAD tells the version control system to display results from a specific commit. Each time you create a new commit, HEAD will point to its parent.

What does Git detached HEAD mean?

HEAD usually points to a branch name, so when you create a new commit, though the branch reference will be updated to point to it, HEAD will remain unchanged. When you switch to another branch, HEAD will be updated to point to it. This means that HEAD is attached to a branch. You may visualize it in the following way.

HEAD attached in Git
This diagram shows us that HEAD points to the master branch, which in turn points to the last commit. That’s the attached HEAD state. Now, let’s try to replicate detached HEAD in Git by checking out one of the commits:

git checkout 87ec91d

As you can see below, HEAD no longer points to the master branch. Instead, it points directly to a commit. This is known as detached HEAD in Git.

detached HEAD in Git

Another way to enter a detached HEAD state is to check out to a remote branch before previously fetching it. If you check out to the origin (main) branch, which is read-only, you will get notified that you are in the detached HEAD state. There are other scenarios as well. For instance, checking out to a specific tag name or adding ^0 on any given branch will result in Git detached HEAD state.

Benefits of detached HEAD in Git

Detached HEAD in Git is a useful state since it gives you the option to navigate to a previous point in the history of your project. Let’s say there is an issue in your project that you are attempting to resolve. A bug appeared, so you want to check if it was already there a few days ago. By using the git log command and filtering the results by the date, you can start the relevant commit hash. From there, you can check out the commit in question and run tests to check the state of the application you are developing.

Besides simply returning to the previous project’s state, another benefit of Git detached HEAD is that you can actually make changes to the history of your project. Here is what the detached HEAD message looks like:

You are in ‘detached HEAD’ state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by switching back to a branch.

As you can see, this way, you are basically creating an alternate history of your project. Now, let’s explore this state by creating additional commits and afterward checking what our repository looks like:

echo “Alternate history” > new-file.txt

git add .

git commit -m “Create new file”

echo “Another line” >> new-file.txt

git commit -a -m “Add a new line to the file”

This results in two additional commits descending from our second commit shown in the diagram above. Now, let’s check what happens when we run git log — oneline:

Git log –oneline

c8f4f8e (HEAD) Add a new line to the file

ec0118f Create new file

87ec91d Add a line to the file

3d11eb0 Create file

That means our diagram currently looks like this:

Git log --oneline

How to fix Git detached HEAD?

First of all, fixing is not quite the term we should use here. If we are attempting to fix something, something is broken. However, as we have mentioned in the introduction to this article, a detached HEAD is a valid state in Git, and as such, it doesn’t require fixing. That’s why we’ll dedicate this section of our article to ways to revert to the original state. 

There are three ways to get back to the original state depending on the reasons you found yourself in detached HEAD mode. Let’s check them out.

You are there unintentionally

In case you had no intention to check out a commit and reach the detached HEAD state in Git, all you have to do in order to revert to a previous state is to check out the branch you were in before. You do this by entering:

git checkout <branch-name>

Git versions 2.23.0 and newer allow you to substitute the checkout command with the switch command. That means you can also type:

git switch <branch-name>

You have experimented with some changes, but now you wish to discard them

Perhaps you wanted to try something new with a couple of commits, but the experiment didn’t produce satisfying results. By switching back to your original branch, you will also discard any changes you have made in the Git detached HEAD state. So, just like in our previous example, all you need to do is enter the following command:

git checkout <branch-name>

You have experimented with some changes, and you wish to keep them

Let’s say you did the same thing as in our previous example, but you wish to keep the changes you made this time. To do so, you need to create a new branch and navigate to it. Whether you choose to create a new branch right after entering Git detached HEAD state or upon making some commits, the results will remain the same, and the changes will be saved. However, you need to ensure that you have a new branch created before switching back to your original branch. Let’s explore this case:

git branch alt-history

git checkout alt-history

You’ll notice that git log –oneline returns the same results as before. The only change is the branch name indicated in the last commit. Let’s take a look:

git log –oneline

c8f4f8e (HEAD -> alt-history) Add a new line to the file

ec0118f Create new file

87ec91d Add a line to the file

3d11eb0 Create file

Here is what our diagram looks like in this case:

git alt-history

How to command Git not to show the detached HEAD message?

Now that we have become familiar with Git detached HEAD state, some of our readers may find it tiresome having to view that message each time they check out a commit. But, there is a way to avoid that message with the following command:

git config advice.detached head false

That way, the change applies only to your current repository. You can add the -global modifier if you wish it to apply to each repository.

Final thoughts

As you can see throughout this article, the detached HEAD state is nothing to worry about. It is not an error message but rather a notification about the less common state in which you currently are. Furthermore, it provides additional opportunities and ways to work in this version control system.

We hope you have enjoyed today’s article and learned new ways to work in Git. In case you require any assistance with your projects or if your business needs custom-coded websites to boost online presence and improve brand reputation, feel free to schedule a call with our agency.

Want to start your creative project today? Fill out this form, and let’s discuss your next steps.

Request Your Proposal
complete form icon
Complete Form
Discovery icon
Discovery
get proposal icon
Get a proposal