While you might not encounter the problem of a detached HEAD, it is important to know about it so that you can avoid it. As a recommendation do not commit on a detached HEAD but if you do, we’ll show you how to save your commits.
In order to understand what the HEAD is, let’s do a refresher on Git’s underlying tree-like structure.
- The Working Directory: Or working tree. It refers to your local directory and
git statuswill give you the state of your working directory.
- HEAD: It is just your current branch last commit snapshot. If you were to switch branches with
git checkoutthen the HEAD will change to the last commit on the branch.
- Index: Or staging area, so when you
git addfiles to commit it adds them to this index.
Understanding the Attached HEAD
Now that we understand that HEAD is just the latest commit on the current branch you are on. By doing
git status it will tell your branch e.g.
On branch master and by doing
git log it will tell your commit history with information such as:
commit 38373004b8f651b58cea64cd629e1e2c18c164a0 (HEAD -> master, origin/master, origin/HEAD) Author: Felipe <email> Date: Wed Sep 29 22:57:59 2020 -0500
Then if we were to change our branch to let’s say development branch with
git checkout development then the HEAD will move to the last commit. So in all these normal cases the head is following us as it is supposed to be attached to a last commit on the branch we are on.
Detaching the HEAD
There are a couple of ways we can detach our HEAD.
- Using the
git checkout --detachcommand.
- Checkout to a commit hash. E.g. If we use the commit from above
git checkout 38373004b8f651b58cea64cd629e1e2c18c164a0
- By adding ^0 on any given branch. E.g.
git checkout master^0.
I’m not sure whether you’d like to intentionally detach HEAD. So the most common case is that by mistake you wanted to checkout to a branch and used a commit hash instead of the branch name.
So what happens after a detached HEAD? You might get a warning similar to this:
$ git checkout 38373004b8f651b58cea64cd629e1e2c18c164a0 Note: checking out '38373004b8f651b58cea64cd629e1e2c18c164a0'. 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 performing another checkout.
Once on a detached HEAD environment, if you do
git status even though you made changes, it will say something like this:
HEAD detached at ac63806 nothing to commit, working tree clean
So it will be like you are frozen in time and everything you do is kind of lost, or merely not going anywhere. Why? Well because the HEAD is not pointing to anything.
Some people find this useful to explore a previous state of the repository without any worries of breaking things.
Re-Attaching the HEAD
You must understand that any of your branches will not be affected if you ever get into a detached state. Now, the best way to reattach the HEAD is to create a new branch.
We can do it as simple as
git checkout -b <branch-name>.
What if we didn’t realize we were without a HEAD and started making changes? Well, here we will need to create a temporary branch and just merge with the branch we need to commit. For example:
git checkout -b temp-branch git checkout master git merge temp-branch
This will commit the changes from your temporary branch into the branch you need them. In this case master.
Today we learned how to detach our HEAD (not literally) and what to do afterwards. Understanding what the HEAD is in the Git inner workings can help us understand special cases such as a detached HEAD.
We also learned to not worry if we ever end up in a detached HEAD state. Just do have in mind that since your HEAD is loose, changes and commits will not be reflected anywhere. So make sure you reattached the HEAD accordingly.