HEAD answers the question: Where am I right now in the repository? It is a pointer to the currently checked-out branch or commit, which contains an immutable snapshot of your entire code base at a given time. Whichever commit
HEAD is referencing directly (using the hash) or by reference (using a branch), it'll always be the commit on which any local changes are based.
Ok, but what does all of this even mean? In this post, I'll explain the above statement in more detail using illustrations, showcasing how
Attached & detached state
First, it's essential to know that the
HEAD pointer can be in either of two states: attached or detached. The default state is attached, where any manipulation of the history is automatically recorded to the branch
HEAD is currently referencing. In a detached state, experimental changes can be made without impacting any existing branch, as
HEAD is referencing the underlying commit directly and is not "attached" to a particular branch.
Still, confusing? Don't worry! The illustration below showcases the two states in a side-by-side comparison. Note that our history only contains two commits (C0 & C1) and one branch (master) with its remote counterpart (o/master).
On the left-hand side,
HEAD is in default attached state where any changes are automatically recorded to a branch; in this particular case, the local
master branch. On the right,
HEAD is in the slightly more uncommon detached state, referencing the commit using its unique hash
It's important to understand that regardless of how the underlying commit is referenced (directly or by reference), its content is automatically unpacked and mirrored to your local Working Tree (e.g., the files and folders on your computer) upon checkout. In the above example, the local Working Tree would be identical in both cases, containing the snapshot of
Now that we know how
HEAD can point to commits directly or by reference; let's see what happens if we manipulate the history by creating a new commit (C2) on top of C1. Again, with the two states side-by-side for easy comparison.
As you can see above, the new commit C2 was created through a
commit operation in both cases. The main difference is that in the attached state the change is automatically recorded in the
master branch. In contrast, in the detached state, the change did not impact any existing branch and
master remained to reference C1.
Similar things would have happened if a rollback operation had been used, such as
reset, but that's a case suitable for a future blog post!
Now, let's look at how to know what
HEAD is currently referencing.
What is HEAD referencing?
As mentioned, most of the time your
HEAD reference will be pointing to a branch, hence in attached state. Whenever a new commit is created on the branch,
HEAD will automatically follow. But, in some cases and during some procedures you'll find yourself with
HEAD in a detached state, where it directly references a commit rather than a branch.
For example, every time you explicitly checkout a commit using its hash, or if you checkout a tag,
HEAD will go into a detached state. There are also other operations such as interactive
rebase that might leave you with
Whenever you want to know which state
HEAD is currently in and what it's referencing, the simplest way is to type
$ git status in your terminal. Git will then let you know the status of your entire Working Tree, including Index (Staging area), but also the state of
Below is a short sequence showing how Git always tries to inform you of your current status of
HEAD. In the example, a commit is first checked out using its hash (
$ git checkout t57lk Switching to 't57lk', you are now in 'detached HEAD' state. $ git status HEAD detached at t57lk
Another easy way to inspect what
HEAD is pointing to is using the command
$ git show HEAD --oneline. It will tell you what
HEAD is currently referencing, but also list all other branches that are also referencing the same commit; notice
HEAD -> master within the parenthesis on the final line below, indicating that
HEAD is pointing to
master – hence, indirectly indicating that
HEAD is in attached state.
$ git checkout master Switched to branch 'master' $ git show HEAD --oneline t57lk (HEAD -> master, o/master) C2
You are in 'detached HEAD' state
Many git beginners believe the message
You are in 'detached HEAD' state to be an error, but in reality, as we've just seen, it just describes your
HEAD pointer's state. "Recovering" from a detached
HEAD state is simple: switch back to an existing branch or create a new one from where you're currently at.
Explicitly inspecting the HEAD pointer (overkill)
If you ever want to explicitly see what
HEAD is referencing you can always inspect the
.git/HEAD file, which is the actual file git uses internally to manage
HEAD. The file contains the name of the branch or commit hash depending on if
HEAD is detached or not.
HEAD is generally something you would never do, but for educational purposes, it can be good to be aware of. In the example below, cat is used, but you can view the file using your regular text editor instead.
@ — the new HEAD alias
1.8.4 of Git, the
@ symbol can be used interchangeably with
HEAD, for convenience. For example, instead of typing
$ git show HEAD --oneline, you can instead write
$ git show @ --oneline.
So, why is the concept of
HEAD two states so important to understand?
With a good understanding of the
HEAD pointer, you can swiftly navigate the history of your repository and perform operations as you see fit. Never again will you be lost in time or misinterpret the information
detached HEAD for an error!
Below is a short cheat sheet illustrating the
HEAD concept; download it! =)
To fully understand how
HEAD works, it's essential also to understand the relationship between
HEAD, Working Tree and Index (Staging area). A deep dive into this interrelation will be published in a future post!
Now that you know what
HEAD is and how it operates, I hope you feel more confident in navigating the history of your repository.
Thanks for reading, and good luck improving your source code management skills!
📫 If you'd like more pieces like this, sign up on the news feed, so you don't miss anything!
As a member, you'll also get instant access to downloadable resources tailored to help you excel with Git!
☝️ Any questions or suggestions, try reaching me on Twitter – @Stjaertfena