[Original] What's HEAD, FETCH_HEAD and ORIG_HEAD in Git
There are many heads in Git:
The most common ones are
Let me elaborate them one by one.
head: A named reference to the commit at the tip of a branch. Heads are stored in a file in
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.
$ 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 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 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!