0

While going through renaming of tags , I came to know that anotated tags are object themselves having their own SHA1 id's. HERE

I also know how git checkout resolves their references. HERE

If $GIT_DIR/ exists, that is what you mean (this is usually useful only for HEAD, FETCH_HEAD, ORIG_HEAD, MERGE_HEAD and CHERRY_PICK_HEAD);

otherwise, refs/ if it exists;

otherwise, refs/tags/ if it exists;

otherwise, refs/heads/ if it exists;

otherwise, refs/remotes/ if it exists;

otherwise, refs/remotes//HEAD if it exists.

Now my question is when I do git checkout some_annotated_tag_name or even git checkout SHA1_ID_OF_ANNOTATED_TAG it switches my HEAD to the commit which annotated tag points to and not to the object of annotated tag.

What is the reason behind this ? If I am mentioning some SHA1 ID , it should take me to that SHA1 Id ?

EDIT : Let us say my annotated tag name is annot. It's SHA1 is 216a2ee6ef4276566081c6dc1ee853bfd1798829 and the SHA1 of the commit it points to is a8b21d7a46903e90d08338fd0311e2ead8d86eac.

Now let use see what result we get.

git checkout annot

Output :

Note: checking out 'annot'.

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 a8b21d7... 3rd

git checkout 216a2ee6ef4276566081c6dc1ee853bfd1798829

Output :

Note: checking out '216a2ee6ef4276566081c6dc1ee853bfd1798829'.

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 a8b21d7... 3rd
Number945
  • 4,631
  • 8
  • 45
  • 83

1 Answers1

2

The document also says that HEAD names the commit on which you based the changes in the working tree. HEAD can point to a branch or a specific commit, and in the final analysis it points to a commit because a branch always points to a commit. The only exception is an unborn branch. When we create a new repository by git init, we'll find the content of .git/HEAD is ref: refs/heads/master. At the moment, master is an unborn branch that waits for the first commit and HEAD is not a valid revision yet. After all, HEAD as a valid revision always point to a commit object.

Unlike a light-weight tag, the annotated one has its own object like a commit. Both tags can point to any one of the four kinds of Git objects, commit, tag, blob and tree, although in most cases they point to commits. If HEAD points to a tag while the tag points to a blob, then HEAD can not be resolved as a commit, which is against the designed use of HEAD. So HEAD can't point to a tag object in the first place.

ElpieKay
  • 27,194
  • 6
  • 32
  • 53
  • 2
    Another way to put this is that Git's internal rules dictate that `HEAD` shall contain either the name of a branch, or some raw hash ID that identifies a commit (never any of the other three types of object). This corresponds to a similar internally-enforced rule that a name that begins with `refs/heads/` must always point directly to a commit object. (You can of course break these rules by messing directly with Git's files, but if you do, and Git breaks, that's your fault. :-) ) – torek May 13 '18 at 20:20