Git: What's HEAD
What is HEAD?
HEAD
refers to a specific commit.
You can see which it is by looking at the file .git/HEAD
in your project directory.
Here's detail:
- A “head” is a “named reference” to the last commit of a branch.
- By default, there is a head called “master”. (look at directory
.git/refs/heads/
) - At any given time, one head is selected as the “current head”.
HEAD
(all capital letters) refers to the “current head”. (see.git/HEAD
)
In other words, think of “heads” as variables, and their values are specific commit id. And HEAD is a specific variable, whose value is the “current” commit id.
How to find what commit is current HEAD?
Look in the file .git/HEAD
.
You can do so by the command
# show the commit id the current HEAD points to cd my_project_dir cat .git/HEAD
Sample output:
~/web $ cat .git/HEAD ref: refs/heads/master ~/web $
The refs/heads/master
is again a reference. It is a file, you can look at .git/refs/heads/master
The content on my disk is: 7cc94381a53ef1e20bfe8a5529ab1aaa616b0696
What is detached HEAD?
When HEAD is pointing to a commit ID directly, instead of a named branch, it's called detached HEAD.
Here's quote from git help glossary
:
detached HEAD
Normally the HEAD stores the name of a branch, and commands that operate on the history HEAD represents operate on the history leading to the tip of the branch the HEAD points at. However, Git also allows you to check out an arbitrary commit that isn’t necessarily the tip of any particular branch. The HEAD in such a state is called “detached”.
Note that commands that operate on the history of the current branch (example: git commit to build a new history on top of it) still work while the HEAD is detached. They update the HEAD to point at the tip of the updated history without affecting any branch. Commands that update or inquire information about the current branch (example: git branch --set-upstream-to that sets what remote-tracking branch the current branch integrates with) obviously do not work, as there is no (real) current branch to ask about in this state.
How to Set HEAD?
You can use git-reset
to set HEAD.
See man git-reset
.
What is HEAD~
HEAD~
is a syntax.
HEAD~
is same asHEAD~1
HEAD~~
is same asHEAD~2
HEAD~~~
is same asHEAD~3
Here's what it means.
HEAD~
means the first parent of HEAD.HEAD~~
means the first parent of first parent of HEAD.HEAD~~~
means the first parent of first parent of first parent of HEAD.
(when there are more than 1 parent, the second etc are ignored. It simply go up the ancestry via 1st parent.)
What is HEAD^
HEAD^
is a syntax.
HEAD^
is same asHEAD^1
HEAD^^
is same asHEAD^2
HEAD^^^
is same asHEAD^3
When current branch's commits never had any 2nd parent, that is, no merge ever happened, then,
HEAD^
and HEAD~
means the same thing.
Else, each occurrence of ^
refers to the 2nd parent, when there's one, or 3rd parent if currently on 2nd parent, etc, and if none, it refers to just parent up wards.
- The
~n
means nth ancestor of the commit, always following the first parent, upward. - The
^n
means nth parent of the commit with respect to merges, going side ways if there are mutiple parents, and if no, going upward.