According to man git checkout
,[1] these are the only things that you
can feed this command:
git checkout [snip] [<branch>]
git checkout [snip] [<commit>]
git checkout [snip] [<pathspc>]
Notably it says nothing about ref
as a general thing that you can make
HEAD
point to—only <branch>
and <commit>
.
Further, the only mention of tags is under the section “Detached
HEAD
” (v2.0
is a tag):
It is sometimes useful to be able to checkout a commit that is not at
the tip of any named branch, or even to create a new commit that is
not referenced by a named branch. Let’s look at what happens when we
checkout commit b (here we show two ways this may be done):
$ git checkout v2.0 # or
$ git checkout master^^
[…]
Notice that regardless of which checkout command we use, HEAD
now
refers directly to commit b. This is known as being in detached HEAD
state.
So if you checkout a commit directly or through a tag the result is the
same; you are in “detached HEAD
” state, pointing directly at a commit.
So I would say that HEAD
may only point to a ref (and no other kind
of ref) of type branch:
# The contents of `.git/HEAD`
ref: refs/heads/main
Or else it has to point directly at an object:
# The contents of `.git/HEAD` (in “detached `HEAD`” state)
17abc2521ca2f1331cc8c4a02b501443fd92f11d
Notes
- Git 2.40.0
.git/HEAD
?git symbolic-ref
to attempt to read a name (any name, not justHEAD
) to see whether it contains a symbolic reference, or a raw hash ID. The command will fail if the reference contains a raw hash ID. This will show that checking out a tag results in a detached HEAD.refs/heads/
. It's not clear exactly what the advantages and disadvantages would be, ifHEAD
could containref: refs/tags/v2.1
for instance. But this is at least currently forbidden.