Jan 8th, 2021 - written by Kimserey with .
In few of our previous posts, we referred to the HEAD, working tree and index when dealing with Git. In today’s post we will look at what those mean with example.
In Git HEAD is known as a reference or “refs”. References are stored under the
/.git folder and HEAD is under
For example if we display the content:
1 2 3 4 5 ❯ cat .git/HEAD ref: refs/heads/master ❯ cat .git/refs/heads/master 1911bf2d5227f92ba0b2f4bc03170e02e7a179fe
We can see that right now HEAD is a reference to another reference which itself a commit sha-1.
This second reference
.git/refs/heads/master is where our
master branch points to on our local repository. This allows us to reference
master instead of
HEAD can simply be referred as
HEAD with for example
git show HEAD.
/,git we can also find
ORIG_HEAD which is the reference kept for safety when doing dangerous operations like
git reset allowing us to reset back to the original head.
So HEAD is simply a reference to the current commit we are working on. It usually points to the branch which itself is a reference to the latest commit on the branch. But HEAD can also sometime be a specific commit in cases of detached HEAD where we checkout a tag or a specific commit.
The working tree is the current tree on which we are working. It’s where our unstaged changes are kept. Git object model is built around files, trees, commits and references. A tree can be seen as directory which links files blob. We can see trees with
ls-tree, for example we show the tree from HEAD:
1 2 3 4 ❯ git ls-tree HEAD 100644 blob 2ae827f56b06d064dd3e65e07e92c5a537aa99d3 .gitignore 100644 blob 42f11063a879b952f89165f7f4fa83ddca178408 HELLO 040000 tree 9d254d776ebe2b8e02e0269116f79976b1c5c306 _data
We see that HEAD is composed of blobs and trees and we can list the content of
_data which is a directory by using the hash.
Similarly we can look at the content of a file with
1 2 ❯ git cat-file -p 42f11063a879b952f89165f7f4fa83ddca178408 Hello%
So the working tree is the current tree we are working on.
Commitish and treeish are words used in Git documentation to refer to an object pointing to a commit or a tree.
The index is a tree containing all files including staged changes. We can see its content with
1 ❯ git ls-files -s
-s includes staged changes.
When doing a
git diff, we can use
git diff --staged to show the diff between the index and HEAD (which is usually a reference to the tip of the local branch checked out).
The index is the stage where all changes are prepared to be committed, once we do:
1 2 3 ❯ git commit -am "Some changes" [master 1328c74] Some changes 1 file changed, 2 deletions(-)
The changes from index are saved into a commit on our local
master, here at
1328c74. From here our changes are inside our local repository and we can compare it to the upstream:
1 ❯ git diff origin/master master
This would compare our local
origin/master. Then we can push our local branch to the upstream wtih
git push to update
origin is known as representing the remote repository. When we talk about remote, we are talking about the remote repository. We can list all our remote repository with:
1 2 3 ❯ git remote -v origin https://....git (fetch) origin https://....git (push)
We can see our
origin repository. Just like HEAD,
origin is also a reference:
1 2 3 4 5 ❯ cat .git/refs/remotes/origin/HEAD ref: refs/remotes/origin/master ❯ cat .git/refs/remotes/origin/master e86ed6b7a9f8e3db7e58dc499728da479d2fac4a
origin remote is used to fetch (or pull) and push. When we clone a repository, the origin is set by default. If we create a new branch that isn’t track by the remote, we can use
-u to set the upstream branch to track the local branch. This is important to let us use
git pull and
git push without arguments.
So to summarize here is a graph showing the flow involved:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 +--------------+ +-------+ +------------------+ +---------+ | | | | | | | | | Working Tree | | Index | | Local Repository | | Remote | | | | | | | | | +------+-------+ +---+---+ +---------+--------+ +----+----+ | | | | | | | | | git add | | | +--------------->+ | | | | | | | | git commit | | | +---------------->+ | | | | | | | | git push | | | +---------------->+ | | | |
In today’s post we looked at the definition of HEAD, working tree, index and remote in Git. Those terms are important terms to understand the Git documentation as they are used throughout the explanations. I hope you liked this post and I see you on the next one!