Mandroid
Mandroid

Reputation: 7478

A query on git HEAD

I am asking this question to understand implementation details of git, so I may be wrong in technical terms.

Going through git scm book, I understand that HEAD can point to a branch(which itself is a pointer to a commit). and also to a commit.

So HEAD can point to two objects of different types.

Is it possible for a pointer to point to objects of diff types(commit and branch dont seem to be connected in terms of hierarchy)?

Upvotes: 0

Views: 45

Answers (1)

torek
torek

Reputation: 488123

In technical but totally-concrete terms, HEAD is actually a file, .git/HEAD. It contains either:

  • the name of a branch, or
  • the hash ID of a commit.

When HEAD contains the hash ID of a commit, that's all it has. Git calls this situation a detached HEAD and the only information available is the commit's hash ID.

When HEAD contains the name of a branch, though, now you have two ways to ask Git about it:

  • Hey, Git, tell me what hash ID HEAD names. Git looks at HEAD, sees that it names master, then looks at master to see what hash ID master names. That's the answer to your question.

  • Or, Hey, Git, tell me what branch HEAD names. Git looks at HEAD, sees that it names master, and tells you master as the answer to your question.

Every branch name always contains the hash ID of exactly one commit, so if HEAD contains a branch name, Git can always do the HEAD-to-hash-ID thing by doing the two steps. When HEAD contains a raw hash ID, though, an attempt to ask Git what branch name it holds gives you an error:

$ git checkout --detach master
HEAD is now at 83232e3864 The seventh batch
$ git symbolic-ref HEAD
fatal: ref HEAD is not a symbolic ref

or, using git rev-parse --symbolic-full-name, just prints HEAD:

$ git rev-parse --symbolic-full-name HEAD
HEAD

Re-attaching HEAD to master makes these both produce branch names:

$ git checkout master
Switched to branch 'master'
$ git symbolic-ref HEAD
refs/heads/master
$ git rev-parse --symbolic-full-name HEAD
refs/heads/master

So that's how HEAD can be either a branch name or a commit hash, except when it can only be a commit hash.

Upvotes: 2

Related Questions