What Is the HEAD in Git: A Complete Guide (with Examples)

In Git, the HEAD is the current state of the branch you’re working in. The HEAD is a pointer that follows you everywhere you go.

If you’ve checked out in any git branch and run git show HEAD, it shows the most recent commit.

$ git show HEAD

commit 8994913e0be924ac5330bf85a35ecb08983731ce (HEAD -> main)
Merge: 59beccd 8ee00b3
Author: artturijalli
Date:   Tue Dec 6 13:19:13 2022 +0200

    Merge branch 'feature'

In a sense, the Git HEAD is you. It points to the tip of your current branch and moves with the branch as you make new commits.

The HEAD can also point to a specific commit instead of a branch. When this happens, you’re in a detached HEAD state.

This guide teaches you what HEAD is in Git, and what kinds of different HEAD notations (HEAD~ HEAD^) you might encounter and how they work.

Let’s jump into it!

What Is HEAD in Git?

In Git, the HEAD is a symbolic reference to where you’re at right now. The HEAD follows you everywhere you go in Git.

If you’ve checked out to a branch, the HEAD references the state of the branch you’re in. In other words, HEAD leads you to the most recent commit in the branch. If you make a new commit to the branch, the HEAD and the branch reference will move together to point to the new commit.

Most tutorials (including this one) say that the HEAD points to the most recent commit in a branch. But in reality, the HEAD references the current branch instead of a particular commit.

If this confuses you, think about it this way: The state of the current branch is what the most recent commit produced. The HEAD, which is a reference to the current branch, is a pointer to this most recent commit, even though it technically points to the branch, not to the commit.

Example

You can check where your head points by running cat .git/HEAD.

This lists the contents of the HEAD file, that is, where the HEAD currently points at.

For example, I have an example project and I’m in the main branch. This is what the cat .git/HEAD command shows me:

This shows that the HEAD indeed points to the main branch.

Detached HEAD in Git

Previously, you learned that the HEAD points to the branch you’re currently in.

But it is possible to make the HEAD point to a specific commit in the past. More specifically, if you checkout to a particular commit, you’re detaching the HEAD from the branch and making it point to a commit. This is known as the detached head state in Git.

To further demonstrate, if I now check out to one of the previous commits in the main branch, the HEAD will point to the checked-out commit instead of the branch.

$ git checkout accf83fb43aabd0f55780657d57e07ffbeeeb1e1

Note: switching to 'accf83fb43aabd0f55780657d57e07ffbeeeb1e1'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at accf83f Change the file contents

From the rather long message above you can see that the HEAD is now pointing to a commit instead of the main branch.

Let’s verify this with cat .git/HEAD:

As you can see, now the HEAD points to a commit instead of a branch. In this restricted mode, you cannot do much—staging and committing isn’t possible because the HEAD doesn’t point to a branch but a commit instead.

The HEAD Is Always You in Git

In Git, the HEAD is you. It follows you everywhere. You cannot lose the HEAD in Git.

Even if you are in the detached HEAD state, you haven’t lost the HEAD. Instead, the HEAD has followed you and now points to a commit rather than to a branch.

Now that you have a better understanding of HEAD in Git, let’s take a look at some notations you may have come across.

Different HEAD Notations You See in Git

Have you wondered what’s the significance of the notations such as HEAD~, HEAD^^^, HEAD@{2}?

This section teaches you what the following HEAD references mean and how they work in Git:

  1. HEAD~ and HEAD~N
  2. HEAD^ and HEAD^N
  3. HEAD@{N}

1. What Is HEAD~?

HEAD~ is a shortcut that refers to the commit that took place before the most recent commit. In a sense, the HEAD~ is the state of the branch one commit before the HEAD commit.

You can view the commit before teh most recent commit by running:

$ git show HEAD~

Using the HEAD~ notation is useful when you need to reference commits but don’t want to look up the commit IDs.

For example, you can check the changes between the 2nd and 3rd most recent commits by:

$ git diff HEAD~ HEAD~~

You can also specify a number after the ~ character to reference a specific number of commits before the HEAD commit.

$ git show HEAD~N

For example, HEAD~2 would reference the commit that is two commits before the HEAD commit (i.e. HEAD~~), and HEAD~3 would reference the commit that is three commits before the HEAD commit (i.e. HEAD~~~).

Here’s an illustration of how the HEAD~ notation works:

2. What Is HEAD^?

HEAD^ is another shortcut that refers to a specific commit in Git. It is very similar to HEAD~. The HEAD^ thus points to the commit that was made before the HEAD commit, on the same branch.

Based on this description, it seems as if HEAD^ and HEAD~ worked the exact same way.

The similarity between HEAD^ and HEAD~ is that you can place consecutive carets or tildes to reference earlier commits.

For example:

  • HEAD^^^ is the third most recent commit.
  • HEAD~~~ is the third most recent commit.

But there’s also a clear difference between HEAD^ and HEAD~ in Git.

You can call HEAD^ followed by a number, such as HEAD^2 but it’s not the same as HEAD^^! (With HEAD~ notation, HEAD~~ is the same as HEAD~2).

HEAD^1 would reference the first parent of the HEAD commit, HEAD^2 would reference the second parent of the HEAD commit (if it exists), and so on.

For example, if your branch is not merged with another branch, the HEAD^2 doesn’t exist.

The number notation with HEAD^ comes into play if you have merged a branch with the current branch. This image illustrates the use of HEAD^ perfectly. The most recent commit, D, is the merge commit of main and feature branch.

So as you can see, the HEAD^1 refers to the most recent commit made in the main branch. The HEAD^2 refers to the most recent commit made in the feature branch before merging. If there was no feature branch merged to the main branch, HEAD^2 wouldn’t exist.

3. What Is HEAD@{N}?

HEAD@{N} is a reference to a specific state of the HEAD pointer in the Git reflog.

In case you didn’t know the git reflog is a reference log that stores all the changes that have been made to the HEAD pointer in a local Git repository.

Each entry in the reflog has a corresponding number, starting at 0 for the most recent entry, and incrementing by 1 for each earlier entry. HEAD@{N} refers to the state of the HEAD pointer at the Nth entry in the reflog.

The git reflog is a valuable tool for managing and tracking Git operations performed in a local repository. It allows you to see a log of all the changes that have been made to the HEAD pointer, which can be useful for identifying when certain commits were made. More importantly, it allows for recovering from mistakes or unintended changes to the repository.

One common use for the reflog is to recover from mistakes, such as undoing a hard reset. With the reflog, you can find the state of the HEAD pointer at the time before you made the mistake to restore the repository to that state.

Summary

Today you learned what is the HEAD in Git.

To take home, the HEAD is a reference to the current state of the local repository. It points to the most recent commit on the branch that is currently checked out. The HEAD can be thought of as a pointer that indicates the current position of the repository.

A great way to view the HEAD is that it’s essentially you! Whatever you do on Git, the HEAD follows. If you create a new commit, the HEAD (and the branch) moves along. If you checkout to a commit in the past, the HEAD follows. The HEAD always points to where you are in the project.

You can reference earlier commits in the branch by adding tildes after HEAD. For example, HEAD~~ refers to two commits before the most recent one.

Thanks for reading. Happy coding!

Read Also

How to Undo Git Reset

Scroll to Top