1

In Git, when we check out to a specific commit using the following command:

git checkout <commit>

If we use the tag (assume that commit has a tag referencing it) for that particular commit, instead of its SHA-1 value in place of < commit >, will the HEAD reference, point to the tag (i.e. will the HEAD act as a symbolic reference) or point to the SHA-1 value (i.e. act as a reference)?

Thank you!

3
  • 3
    Just try checking out a tag and then looking at .git/HEAD?
    – larsks
    Commented Dec 24, 2020 at 14:32
  • 1
    You can also use git symbolic-ref to attempt to read a name (any name, not just HEAD) 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.
    – torek
    Commented Dec 24, 2020 at 19:13
  • 1
    As an aside, symbolic refs could, in theory, attach to any ref (existing or not), but Git currently constrains them to attach only to branch names, i.e., refs whose full name starts with refs/heads/. It's not clear exactly what the advantages and disadvantages would be, if HEAD could contain ref: refs/tags/v2.1 for instance. But this is at least currently forbidden.
    – torek
    Commented Dec 24, 2020 at 19:15

3 Answers 3

3

As far as I know, a Git tag is basically just a pointer to some commit. This is similar to a branch name, which logically also points to the recent commit of a branch. Checking out either a tag name or a branch name will move the HEAD to the relevant commit.

To your exact question, a tag is a pointer to a commit (which has a unique SHA-1 hash value), and checking out a tag will move the HEAD to point to the commit referred to by the tag.

2

you can see exactly what the HEAD is referencing:

<.git/HEAD

HEAD is just a file.

0

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

  1. Git 2.40.0

Not the answer you're looking for? Browse other questions tagged or ask your own question.