In git, HEAD
is typically "attached" to a local branch (i.e. it points to a local branch). However, in some cases, the HEAD
may be "detached" which means that whatever is checked-out locally does not point to a local branch. Such can be the case, for example, in the following instances:
- When you
checkout
a specific commit; - When you
checkout
a specific tag; - When you
checkout
a remote branch.
When you have a detached HEAD
, executing the cat .git/HEAD
or git status
command would show you that HEAD
is pointing to a commit id/hash and not to a local branch.
When HEAD
is detached, commits still work (as they normally would), however, the difference is that no named branch gets updated. It is like you're working on an anonymous branch.
Detached HEAD
When Checking-Out a Specific Commit
When you checkout
a specific commit, it is not connected to any local branch, and as a result, you end up with a detached HEAD
. For example:
git checkout b8a076940ae86b8c5fc26dd43cd5d2aa7e95d308
This would, for example, show the following message (if you have the setting config variable advice.detachedHead
set to true
):
Note: switching to 'b8a076940ae86b8c5fc26dd43cd5d2aa7e95d308'. 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. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -c with the switch command. Example: git switch -c <new-branch-name> Or undo this operation with: git switch - Turn off this advice by setting config variable advice.detachedHead to false HEAD is now at b8a0769 ...
Detached HEAD
When Checking-Out a Specific Tag
A tag is essentially a label to mark a specific commit in the history. Therefore, when you checkout
a specific tag, (similar to checking-out a commit) it is not connected to any local branch, and as a result, you end up with a detached HEAD
. For example:
git checkout tags/v1.0.0
This would, for example, show the following message (if you have the setting config variable advice.detachedHead
set to true
):
Note: switching to 'tags/v1.0.0'. 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. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -c with the switch command. Example: git switch -c <new-branch-name> Or undo this operation with: git switch - Turn off this advice by setting config variable advice.detachedHead to false HEAD is now at f8696ac ...
Detached HEAD
When Checking-Out a Remote Branch
When you checkout
a remote branch that you're not tracking (i.e. there is no local branch that is connected to the remote branch), you end up with a detached HEAD
. For example:
git checkout origin/main
This would, for example, show the following message (if you have the setting config variable advice.detachedHead
set to true
):
Note: switching to 'origin/main'. 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. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -c with the switch command. Example: git switch -c <new-branch-name> Or undo this operation with: git switch - Turn off this advice by setting config variable advice.detachedHead to false HEAD is now at adbaa7c ...
In comparison, if you use the git switch
command instead of git checkout
to switch to a remote branch (without tracking it), it would fail:
git switch origin/main fatal: a branch is expected, got remote branch 'origin/main'
This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.