Reputation: 7478
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
Reputation: 488123
In technical but totally-concrete terms, HEAD
is actually a file, .git/HEAD
. It contains either:
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