Header

What is a "detached HEAD" in a Git repository?

Find out more about the detached HEAD state in Git

You may find yourself in an odd state when working on your repository. When working on it, running git status might return the following output:

$ git status
HEAD detached at 8fd3350
nothing to commit, working tree clean

This means that at some point, you've run git checkout on a specific commit. In Git, the checkout command is often used for switching between between branches, i.e. git checkout master, but it can also be used to change your working copy to the state is was in a certain commit.

When you checkout a branch, your working copy will be changed to the HEAD, or the very latest commit, meaning you can continue working on the repository in its "current" state.

However, if you run git checkout on a specific commit, you won't be at the HEAD of the branch, therefore Git can't add any commits you create in the correct place. As a result of this, you'll be "detached" from the end of the branch and you can make changes and commit them, but they won't impact any branches.

Git checkout 8fd3350c

When you run git checkout on a specific commit, you'll see the following:

$ git checkout 8fd3350cf6fba8bcd4abc7233d4ff6b81dd6ed3c
Note: checking out '8fd3350cf6fba8bcd4abc7233d4ff6b81dd6ed3c'.

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.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 8fd3350 Add the correct link to Brie

Commit your changes to a new branch

If you do any work on the repository and want to create any commits during the detached HEAD state, it's not a problem. You just need to create a new branch and push your commits there.

$ git checkout -b my_new_branch
Switched to a new branch 'my_new_branch'

$ git push --set-upstream origin my_new_branch
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 303 bytes | 101.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'my_new_branch' on GitHub by visiting:
remote:      https://github.com/robertlyall/shop/pull/new/my_new_branch
remote:
To github.com:robertlyall/shop.git
 * [new branch]      my_new_branch -> my_new_branch
Branch 'my_new_branch' set up to track remote branch 'my_new_branch' from 'origin'.

Notice that we've added the --set-upstream origin my_new_branch switch to the command. This is necessary because the branch doesn't exist on the remote and we need to be able to track further changes to it.

Once you've done that, you'll be switched to the HEAD of your new branch and you can continue working as normal, or switch to another branch as required.

$ git status
On branch my_new_branch
Your branch is up to date with 'origin/my_new_branch'.