You see the Git documentation saying things like
The branch must be fully merged in HEAD.
But what is Git HEAD
exac
You can think of the HEAD as the "current branch". When you switch branches with git checkout
, the HEAD revision changes to point to the tip of the new branch.
You can see what HEAD points to by doing:
cat .git/HEAD
In my case, the output is:
$ cat .git/HEAD
ref: refs/heads/master
It is possible for HEAD to refer to a specific revision that is not associated with a branch name. This situation is called a detached HEAD.
A great way to drive home the point made in the correct answers is to run
git reflog HEAD
, you get a history of all of the places HEAD has pointed.
I recommend this definition from github developer Scott Chacon [video reference]:
Head is your current branch. It is a symbolic reference. It is a reference to a branch. You always have HEAD, but HEAD will be pointing to one of these other pointers, to one of the branches that you're on. It is the parent of your next commit. It is what should be what was last checked-out into your working directory... This is the last known state of what your working directory was.
The whole video will give a fair introduction to the whole git system so I also recommend you to watch it all if have the time to.
There is a, perhaps subtle, but important misconception in a number these answers. I thought I'd add my answer to clear it up.
What is
HEAD
?
HEAD
is a symbolic reference pointing to wherever you are in your commit history. It follows you wherever you go, whatever you do, like a shadow. If you make a commit, HEAD
will move. If you checkout something, HEAD
will move. Whatever you do, if you have moved somewhere new in your commit history, HEAD
has moved along with you. To address one common misconception: you cannot detach yourself from HEAD
. That is not what a detached HEAD state is. If you ever find yourself thinking: "oh no, i'm in detached HEAD state! I've lost my HEAD!" Remember, it's your HEAD. HEAD is you. You haven't detached from the HEAD, you and your HEAD have detached from something else.
HEAD
can point to a commit, yes, but typically it does not. Let me say that again. Typically HEAD
does not point to a commit. It points to a branch reference. It is attached to that branch, and when you do certain things (e.g., commit
or reset), the attached branch will move along with HEAD
. You can see what it is pointing to by looking under the hood.
cat .git/HEAD
Normally you'll get something like this:
ref: refs/heads/master
Sometimes you'll get something like this:
a3c485d9688e3c6bc14b06ca1529f0e78edd3f86
That's what happens when HEAD
points directly to a commit. This is called a detached HEAD, because HEAD
is pointing to something other than a branch reference. If you make a commit in this state, master
, no longer being attached to HEAD
, will no longer move along with you. It does not matter where that commit is. You could be on the same commit as your master branch, but if HEAD
is pointing to the commit rather than the branch, it is detached and a new commit will not be associated with a branch reference.
You can look at this graphically if you try the following exercise. From a git repository, run this. You'll get something slightly different, but they key bits will be there. When it is time to checkout the commit directly, just use whatever abbreviated hash you get from the first output (here it is a3c485d
).
git checkout master
git log --pretty=format:"%h: %d" -1
# a3c485d: (HEAD -> master)
git checkout a3c485d -q # (-q is for dramatic effect)
git log --pretty=format:"%h: %d" -1
# a3c485d: (HEAD, master)
OK, so there is a small difference in the output here. Checking out the commit directly (instead of the branch) gives us a comma instead of an arrow. What do you think, are we in a detached HEAD state? HEAD is still referring to a specific revision that is associated with a branch name. We're still on the master branch, aren't we?
Now try:
git status
# HEAD detached at a3c485d
Nope. We're in 'detached HEAD' state.
You can see the same representation of (HEAD -> branch)
vs. (HEAD, branch)
with git log -1
.
HEAD
is you. It points to whatever you checked out, wherever you are. Typically that is not a commit, it is a branch. If HEAD
does point to a commit (or tag), even if it's the same commit (or tag) that a branch also points to, you (and HEAD
) have been detached from that branch. Since you don't have a branch attached to you, the branch won't follow along with you as you make new commits. HEAD
, however, will.