In Git terminology, the HEAD is a pointer or a reference to the most recent commit of the currently checked-out branch. The current checked-out branch is also known as the HEAD branch. Let's learn more about HEAD in Git.
What is HEAD?
- As discussed above, the HEAD is a reference to the last commit of our current branch. It is the last committed state of our project.
- We can think of the HEAD as our current working branch. This is because the HEAD does not point directly to a commit but instead, it points to a branch.
- The branch itself is a pointer that references the last commit that was made on it.
- The HEAD is automatically updated by Git if we add new commits to the current branch or we switch to a different branch.
Viewing the HEAD
Git stores the information about the HEAD in the .git/HEAD file. We can view its content by using the Linux command cat(short for concatenate).
$ cat .git/HEAD
As we can see in the image below, the file does not store any commit information but instead, it has the name of our currently checked-out branch(master in this case).
We can view the information about the commit to which the HEAD points by using the Git Show command.
$ git show HEAD
We can also use the Git Log command to view the last commit of our current branch.
$ git log -1
We can see in the image below that HEAD is pointing to the master branch(HEAD -> master). This is proof that under normal circumstances the HEAD points to the currently checked-out branch.
Normally, the HEAD will reference the current branch but we can move the HEAD to some other point. Whenever the HEAD directly points to a commit then the HEAD is said to be detached. Detached means that the HEAD no longer points to the current branch tip. A HEAD can get detached if we check out a commit, a tag, or a remote branch. The Detached HEAD is a completely stable state and we can view the history and experiment with things in this state.
When in a detached HEAD state, the .git/HEAD file will not have any branch name but instead it will store the hash of the commit that the HEAD references.
Making New Commits in a Detached HEAD State
- We can make new commits in the Detached HEAD state but these commits will not belong to any of the existing branches.
- If we add a new commit and then checkout to a different branch, then these commits may get lost.
- A solution to this problem is to create a new branch based on these new commits. This way we will have a reference to these commits and we will not lose them.
Consider the following scenario to better understand the concept of detached HEAD.
Suppose we have a single branch(called master) in our repository with just three commits(A --- B --- C). We can view the history of commits using the following Git Log command.
Now, let's use the Git Checkout command to move our HEAD to commit B. When we do this, Git tells us that we are in a detached HEAD state.
Let's make a new empty commit D. The HEAD is still detached and will now point to the new commit D.
Let's check out our master branch and view the commit history. When we check out master, Git also gives us a warning message. We can see that commit D is not present in it.
Git has an automatic garbage collection mechanism that will remove all the unreferenced objects after a certain period of time. If we do not create a new reference to commit D then it will be removed from our repository. We can create a new branch based on this commit point but we will need the hash of the commit to do this.
HEAD is just a reference to the most recent commit of our current branch. We can think of HEAD as the last committed state of our repository. In a normal state, the HEAD will point to a branch, and the branch(which is itself a pointer) points to the most recent commit. We can move our HEAD to point to some other commit using the Git Checkout command. When HEAD directly points to a commit then it is called a Detached HEAD. It is a completely stable state and we can add new commits in a detached HEAD state but we must create a new reference to them as they might get lost.