Git HEAD
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.
![Git HEAD](LAZY_IMG_PLACEHOLDER)
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).
![Viewing the content of .git/HEAD file](LAZY_IMG_PLACEHOLDER)
We can view the information about the commit to which the HEAD points by using the Git Show command.
$ git show HEAD
![Viewing the commit information to which the HEAD points.](LAZY_IMG_PLACEHOLDER)
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.
![Using Git Log to see that HEAD points to the master branch which in turn points to the most recent commit.](LAZY_IMG_PLACEHOLDER)
Detached HEAD
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.
![Git Detached HEAD](LAZY_IMG_PLACEHOLDER)
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.
![Viewing the content of .git/HEAD file when in the HEAD is detached](LAZY_IMG_PLACEHOLDER)
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.
![Viewing the commit history of the master branch](LAZY_IMG_PLACEHOLDER)
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.
![Checking out a commit will make our HEAD get detached.](LAZY_IMG_PLACEHOLDER)
Let's make a new empty commit D. The HEAD is still detached and will now point to the new commit D.
![Adding a new commit in the detached HEAD state](LAZY_IMG_PLACEHOLDER)
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.
![Moving back to the master branch](LAZY_IMG_PLACEHOLDER)
![The commit created in the detached HEAD state is not a part of the commit history of the master branch.](LAZY_IMG_PLACEHOLDER)
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.
Summary
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.