HEAD: Where Are We? Where Were We?

This page starts with the example git repository we created in Commits and referring to commits.

We have 2 commits in the repository. So how does git know which is the current commit for a command like git log?

Git uses the HEAD variable, which by default, is a reference to the current (most recent) commit. In our example, the most recent commit is labeled C2 in the diagram:

head

Adding Commits Changes HEAD

Let’s add one more commit, and then start playing with the repository:

$ echo Last line added. >> README 
$ git commit -a -m"Final commit." 
[master 9c65d51] Final commit.
 1 files changed, 1 insertions(+), 0 deletions(-)
$ git log
commit 9c65d51b2c8f405debdf9b100505f814981e8940
Author: Tim Flagg <me@gitguys.com>
Date:   Wed Feb 23 18:00:13 2011 -0800

    Final commit.

commit 70d1f90caa3343c1ea4a7ba238e4ae4cf9df28a0
Author: Tim Flagg <me@gitguys.com>
Date:   Wed Feb 23 17:00:59 2011 -0800

    Added a second line.

commit 35ede5c916f88d8ba5a9dd6afd69fcaf773f70ed
Author: Tim Flagg <me@gitguys.com>
Date:   Wed Feb 23 16:43:57 2011 -0800

    Initial commit

The commits in the repository now look like this:

master

The window produced by gitg looks like this, showing the master branch at the most recent commit:

3 commits

Digging around more with git show and HEAD

The git show command reports the changes introduced by the most recent commit:

$ git show
commit 9c65d51b2c8f405debdf9b100505f814981e8940
Author: Tim Flagg <me@gitguys.com>
Date:   Wed Feb 23 18:00:13 2011 -0800

    Final commit.

diff --git a/README b/README
index b0ed415..953937c 100644
--- a/README
+++ b/README
@@ -1,2 +1,3 @@
 This is the README file.
 One more line.
+Last line added.

Many git commands, such as git log and git show use HEAD as the commit to report on. However, you can specify a different the parent commit for git show to report on by using the ~ character (“tilde”).

For example, to show the commit from the parent of HEAD (which is the parent of the most recent commit), you use HEAD~:

$ git show HEAD~
commit 70d1f90caa3343c1ea4a7ba238e4ae4cf9df28a0
Author: Tim Flagg <me@gitguys.com>
Date:   Wed Feb 23 17:00:59 2011 -0800

    Added a second line.

diff --git a/README b/README
index bccdfbd..b0ed415 100644
--- a/README
+++ b/README
@@ -1 +1,2 @@
 This is the README file.
+One more line.

Or to refer to the commit before HEAD~ (which is the very first commit made to the repository), you can use either HEAD~~ or HEAD~2:

$ git show HEAD~2
commit 35ede5c916f88d8ba5a9dd6afd69fcaf773f70ed
Author: Tim Flagg <me@gitguys.com>
Date:   Wed Feb 23 16:43:57 2011 -0800

    Initial commit

diff --git a/README b/README
new file mode 100644
index 0000000..bccdfbd
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+This is the README file.

HEADs

What happens when we try to make a reference to before the first commit? An error, as you might expect. Since we have only 3 commits in the repository, we can’t go back farther than HEAD~2:

$ git show HEAD~3
fatal: ambiguous argument 'HEAD~3': unknown revision or path not in the working tree.

Hashes Are Always Accepted Here

If you prefer, you can refer to a commit by its hash. For example, the first commit’s hash, as reported by git log starts with 35ede5:

$ git show 35ede5
commit 35ede5c916f88d8ba5a9dd6afd69fcaf773f70ed
Author: Tim Flagg <me@gitguys.com>
Date:   Wed Feb 23 16:43:57 2011 -0800

    Initial commit

diff --git a/README b/README
new file mode 100644
index 0000000..bccdfbd
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+This is the README file.

There are quite a few different ways git allows you to specify which commit you would like to refer to in addition to the hash or using HEAD.

Behind The Scenes: Where Is The HEAD?

The contents of the git HEAD variable is stored in a text file in the .git/HEAD:

 $ cat .git/HEAD
ref: refs/heads/master

That is telling us that we need to look at the file refs/heads/master in the .git directory to find out where HEAD points:

 $ cat .git/refs/heads/master
9c65d51b2c8f405debdf9b100505f814981e8940

Next: Creating And Playing With Branches
Previous: Commits And Referring To Commits

Related: