1.2 Git Basics: The Three Trees
In this lesson, I’ll explain Git’s three trees. You’ll see the role of each and how they interact as code is updated and committed.
- The working directory is where new changes are made to the codebase. You can edit, create and delete files directly in the working directory.
- The index is where changes are staged. Files are
added to the index, where they are prepared for packaging in a commit object.
- The HEAD is a pointer to a specific branch and commit in the repository. Files are checked out from the HEAD to the working directory and are
committed from the index to the branch pointed to by HEAD.
1.2 Git Basics: The Three Trees
To better understand how git is operating, we can use the metaphor of the three trees. These trees are sort of different collections of files for the workflow of adding and retrieving commits give users three different versions of files. Git uses the working directory, the index and something called head for creating and for retrieving commits. Each of these trees has a different job. One tree to provide some changes. One tree to stage them. And one to point to your last commit on a branch in your git repo. By the way, we're not talking about trees as a data structure. In this scenario, it's simply a metaphor that aids of understanding what goes on under the hood. But forget about the name tree for now. It's not too important. It's an abstraction anyway. Think of it as different versions of files. Files, whose contents can be changed are in your working directory. Files placed in your index are getting prepared to be packaged into a commit object. These commits are saved in your git repository. Files that have already been committed are compressed files. They are hashed through a SHA-1, a cryptographic hash function. Both file versions in the index and commit themselves are saved in the git repo, which is simply a .git rectory at the root level of your wrap. The working directory represents the actual files on your computer's file system that are available to your code editor to apply changes. The working directory is a version of a particular commit, a particular snapshot of a project that you checked out. It is the version of your git history that head is pointing at, at any given moment. Checkout means that you have the decompressed versions of files that were pulled out of your git repository, available for editing. The index represents what is being tracked. You could also say that it's a list of all the files that are relevant for your git repository. The index goes by a couple of names. When people talk about the staging area, staged file, cache, directory cache they are all talking about the index. You can see the index as the draft zone for your next commit, a temporary area to prepare the next commit. Head is the part of git that points to your branches like the master branch by default. It's a reference, it is a pretty simple but hugely important job. Head points to the currently checked out branch and that in turn points back to the last commit from that branch. Head can move not only in time, by that I mean, when you check out previous commits but it also moves when you create new branches or simply switch to other branches. It's also the point in your git history that you can place your next commit upon the parent for your next commit. With every new commit, it replaces its reference to the branch currently checked out, by default, the master branch, of course. So, in effect, head is a reference that frequently changes and points to two things. The branch itself and through that, the last commit on that branch. Let's have a closer look at the workflow of dealing with files in git. It is essential to understand how all these pieces fit together. You'll have a much easier time to make sense of more advanced features and concepts and git after that. In the case in front of you, we have committed two versions of our file. And you can see that the versions in the repo, the index and the working directory are one and the same. Since these files are already tracked, git will notice any differences when you change any of these tracked files in the working directory. When you run the git status command, you will see a list of files that have been changed, colored in red. This indicates that you have differences between your working directory represented by the code in your code editor. And your index representing versions of files from a particular commit, most commonly, the last commit. You can now run the git add command to put these changes from the working directory into the index you staged the files. Git status will then show the files that are added to the index colored in green. This means that your changes are ready to be packaged into a new commit, which head can point to and build upon. A green list of files simply means that the versions of the staged files in the index are different from the versions of files that were already committed previously. When you run git commit, these staged files will be put into a new commit object. The git commit command will save the actual file names, the contents of each file of the information, metadata and such, in a new object. This commit object that now lives in a .git directory in your repo, will be the new reference that head is pointing at. It points back to previous commits, being the tip of the iceberg in a way. After we've created our commit object, we are back at the beginning of the cycle. The commit that head points to in the repo is again matching the versions in the index and the working directory, which is ready for new changes to be staged and committed. End of story.