There are many heads in Git: head
, HEAD
, ORIG_HEAD
, FETCH_HEAD
, MERGE_HEAD
and CHERRY_PICK_HEAD
.
The most common ones are head
, HEAD
, ORIG_HEAD
, FETCH_HEAD
.
Let me elaborate them one by one.
head
head: A named reference to the commit at the tip of a branch. Heads are stored in a file in $GIT_DIR/refs/heads/
directory.
In the top level of your project, show the branches in your repo:
$ ls .git/refs/heads
daily main
Show the commit hash of each branch:
$ cat .git/refs/heads/main
26555cbab836f2b1e1a45d93e9b53b0ccbe48c2f
$ cat .git/refs/heads/daily
254036f1d9c2ecee235cae198c822d9209a2ca7c
Verify the commit hash by git log
$ git log --online
254036f (HEAD -> daily) Go about learning Git' heads
26555cb (main) publish the translation post
The matched hash proved that head
is a pointer to the commit at the tip of a branch.
HEAD
$ cat .git/HEAD
ref: refs/heads/daily
We can see HEAD -> daily
which means that HEAD
is pointing to the daily
branch, if you run git checkout main
, you will see that HEAD
is pointing to the main
branch at this moment:
$ git checkout main
$ git log --online
26555cb (HEAD -> main) publish the translation post
24a679c do some stuff
$ cat .git/HEAD
ref: refs/heads/main
HEAD is like a pointer that points to the current branch. When you checkout a different branch, HEAD changes to point to the new one.
But keep in mind that HEAD
is not the current branch, otherwise is the name given to the commit from which the working tree’s current state was initialized. In more practical terms, it can be thought of as a symbolic reference to the checked-out commit.
FETCH_HEAD
FETCH_HEAD
is a short-lived ref, to keep track of what has just been fetched from the remote repository. It does not just contain a single branch but all the remote branch information that was last fetched. It is a reference to the tip of the last fetch, whether that fetch was initiated directly using the fetch command or as part of a pull. The current value of FETCH_HEAD
is stored in the .git folder in a file named, you guessed it, FETCH_HEAD
which looks like this typically:
e03ef7e18694ff33ac61ba3ee927228f75d9b634 branch 'main' of https://github.com/hustnzj/<my-repo-name>
079d80cfbe4988317858e5509c322f5b61b9b26c not-for-merge branch 'test' of https://github.com/hustnzj/<my-repo-name>
dfb32906005c40ca709772ed45de68c25b56b07a not-for-merge branch 'daily' of https://github.com/hustnzj/<my-repo-name>
Note how all branches but one are marked not-for-merge. The odd one is the branch that was checked out before the fetch. In summary: FETCH_HEAD
essentially corresponds to the remote version of the branch that’s currently checked out.
If you merge now, the commit at the tip of the remote branch main
is merged into the commit at the tip of your current local branch main
in this case.
ORIG_HEAD
ORIG_HEAD
is created by commands that move your HEAD
in a drastic way, to record the position of the HEAD
before their operation, so that you can easily change the tip of the branch back to the state before you ran them.
For example, you use git reset
to go to the specified state. The --hard
mode is so dangerous that you are likely to lose data.
$ git reset --hard HEAD~5
ORIG_HEAD
comes into its own when you mess up and want to return the previous position.
$ git reset ORIG_HEAD
That’s all! Hope the article clear up some doubts and uncertainties in your daily work!
References
Git - gitglossary Documentation
What is HEAD in Git? - Stack Overflow
What does FETCH_HEAD in Git mean? - Stack Overflow.)
Git - gitrevisions Documentation
本作品採用《CC 協議》,轉載必須註明作者和本文連結