HEAD and Three Trees - Git
1. Three trees#
Git as a system manages and manipulates three trees in its normal operation:
Tree | Role |
---|---|
HEAD | Last commit snapshot, next parent |
Index | Proposed next commit snapshot |
Working Directory | Sandbox |
The Git index is a critical data structure in Git. It serves as the “staging area” between the files you have on your filesystem and your commit history. When you run git add
, the files from your working directory are hashed and stored as objects in the index, leading them to be “staged changes”. When you run git commit
, the staged changes as stored in the index are used to create that new commit.
2. HEAD#
2.1. HEAD is YOU#
HEAD
is a symbolic reference pointing to wherever you are in your commit history. It follows you wherever you go, whatever you do, like a shadow. If you make a commit, HEAD
will move. If you checkout something, HEAD
will move. Whatever you do, if you have moved somewhere new in your commit history, HEAD
has moved along with you. To address one common misconception: you cannot detach yourself from HEAD
. That is not what a detached HEAD state is. If you ever find yourself thinking: “oh no, i’m in detached HEAD state! I’ve lost my HEAD!” Remember, it’s your HEAD. HEAD is you. You haven’t detached from the HEAD, you and your HEAD have detached from something else.
Acutally, HEAD is just a special pointer that points to the local branch you’re currently on.
$ cat .git/HEAD
ref: refs/heads/hugo-blog
Sometimes you’ll get something like this:
a3c485d9688e3c6bc14b06ca1529f0e78edd3f86
That’s what happens when HEAD
points directly to a commit. This is called a detached HEAD, because HEAD
is pointing to something other than a branch reference.
In Git, HEAD refers to the currently checked-out branch’s latest commit. However, in a detached HEAD state, the HEAD does not point to any branch, but instead points to a specific commit or the remote repository.
2.2. What can HEAD attach to?#
HEAD
can point to a commit, yes, but typically it does not. Let me say that again. Typically HEAD
does not point to a commit. It points to a branch reference. It is attached to that branch, and when you do certain things (e.g., commit
or reset
), the attached branch will move along with HEAD
.
HEAD
is you. It points to whatever you checked out, wherever you are. Typically that is not a commit, it is a local branch. If HEAD
does point to a commit (or tag), even if it’s the same commit (or tag) that a branch also points to, you (and HEAD
) have been detached from that branch. Since you don’t have a branch attached to you, the branch won’t follow along with you as you make new commits. The HEAD
, however, will.
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/GN36mrrM12k?autoplay=0&controls=1&end=0&loop=0&mute=0&start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
</div>
Source:
https://stackoverflow.com/a/54935492/16317008