When a git commit is done (to “check in” the updates to the repository), git creates a new commit object, which is also saved to the git repository. The commit object includes, at a minimum:
- The hash of the Git tree that represents the state of the index at the time of the commit. In Diagram 2, below, the commit object’s tree refers hash 39179a1 which is the green triangle at the top of the diagram.
- Commiter: The name and email address of who did the git commit, along with a date/time.
- Comment: A text comment that summarises the reason for the commit (for example “Feature #412 implemented!“).
A Commit Has A Hash Too
Since commit objects are part of the object database, they not only have a hash value, but are referred to by their hash.
For the commit example, we will start with the same sample git repository as used for the git tree section.
Click on the thumbnails to see the “the new commit” and “after the new commit” state of the git object store.
- Diagram 1 shows the git object store without a commit object. The hashes of the objects are shown below and to the left of the objects.
- Diagram 2 shows the git object store includes the commit object.The git tree that is referenced in a commit includes the complete state of the index when the commit was done. This means that after every git commit, git has a complete record of the contents of every file and directory that was in the index to be committed at the time of the commit.The commit object’s tree refers to hash 39179a1 which is the git tree represented by the green triangle at the top of the diagram.Also note in Diagram 2, the HEAD pointer, which points to the most recent commit on the current branch.
In addition to the git tree, commiter and comment, a commit may also include any and all git trees that are parents of this commit:
- The first time you commit to a brand new git repository, there will not be a parent tree included in the git commit.
- The second time you commit to a git repository, the parent will be the git commit‘s hash. In the above example, the git hash is 126af20 as shown in the git session.
- If a commit has 2 or more parents, then a “git merge” has occurred: 2 or more different branches were merged into this commit.
A commit can also contain the Author field which can be different than the “committer. It’s possible one person is the author of code, and then makes the code available to someone in QA or in charge of a repository who then adds/commits the code to the repository.
Adding another directory, file and commit
Let’s say we need to start on our test plan, and want to store the test plan in the git repository in the filename plan in a new directory named test.
- Diagram 2, shown once again, below, shows the git object store where we left off with the one commit.
- Diagram 3 shows the git object store with the new test directory and the new file named “plan”. After running git commit, a new commit object was added.The new commit object points to a newly created git tree object: the git tree object points to the current complete state of the git index at the time of the git commit.
Notice that the HEAD changed to the newest commit object at hash 7fd2d16.
Click on the thumbnails to see the “before the new commit” and “after the new commit” state of the git object store.
A note about a Commit Parent
- The new commit shown in Diagram 3 has both a tree reference and a parent reference. The first commit did not have a parent reference. The parent reference refers to the previous (older) commit.
- The new tree references:
- The new tree (“test“) and its new blob (“plan“).
- The previous blobs and trees (“README” blob, src and docs trees with their blobs).
Git has a complete picture of what files and directories were in the index and stores this as part of the commit. For the new commit, git created a new tree which pointed to the new and existing blobs and trees.