源自:http://www.gitguys.com/topics/head-where-are-we-where-were-we/
HEAD: 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:
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 Date: Wed Feb 23 18:00:13 2011 -0800 Final commit. commit 70d1f90caa3343c1ea4a7ba238e4ae4cf9df28a0 Author: Tim Flagg Date: Wed Feb 23 17:00:59 2011 -0800 Added a second line. commit 35ede5c916f88d8ba5a9dd6afd69fcaf773f70ed Author: Tim Flagg Date: Wed Feb 23 16:43:57 2011 -0800 Initial commit
The commits in the repository now look like this:
The window produced by gitg looks like this, showing the master branch at the most recent commit:
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
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 useHEAD~:
$ git show HEAD~
commit 70d1f90caa3343c1ea4a7ba238e4ae4cf9df28a0
Author: Tim Flagg
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 eitherHEAD~~ or HEAD~2:
$ git show HEAD~2
commit 35ede5c916f88d8ba5a9dd6afd69fcaf773f70ed
Author: Tim Flagg
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.
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 with35ede5:
$ git show 35ede5
commit 35ede5c916f88d8ba5a9dd6afd69fcaf773f70ed
Author: Tim Flagg
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