A commit is probably the object type most familiar to git users, as it’s what they are used to creating with the git commit commands.

However, the commit does not directly contain any changed files or data. Rather, it contains mostly metadata and pointers to other objects which contain the actual contents of the commit.

A commit contains a few things:

You can see the contents of any commit like this:

$ git cat-file commit 5bac93
tree 04d1daef...
parent b7850ef5...
author Geddy Lee <[email protected]>
commiter Neil Peart <[email protected]>

First commit!

Tree

A very important note is that the tree objects stores EVERY file in your project, and it stores whole files not diffs. This means that each commit contains a snapshot of the entire project*.

*Technically, only changed files are stored. But this is more an implementation detail for efficiency. From a design perspective, a commit should be considered as containing a complete copy of the project.

Parent

The parent line contains a hash of another commit object, and can be thought of as a “parent pointer” that points to the “previous commit”. This implicitly forms a graph of commits known as the commit graph. Specifically, it’s a directed acyclic graph (or DAG).