Types of git objects¶
If you have read Curious git, you know that git stores different types
of objects in .git/objects
. The object types are:
commit;
tree;
blob;
annotated tag.
Here we make examples of each of these object types in a new repository.
First we make the working tree and initialize the repository:
$ mkdir example_repo
$ cd example_repo
$ git init
Initialized empty Git repository in /Volumes/zorg/mb312/dev_trees/curious-git/working/example_repo/.git/
Next we make an example commit:
$ echo "An example file" > example_file.txt
$ git add example_file.txt
$ git commit -m "An example commit"
[main (root-commit) eebf020] An example commit
1 file changed, 1 insertion(+)
create mode 100644 example_file.txt
From Curious git, we expect there will now be three objects in the
directory .git/objects
, one storing the backup of example_file.txt
,
one storing the directory listing for the commit, and one storing the commit
message:
objects
├── 2f
│ └── 781156939ad540b2434d012446154321e41e03 [32B]
├── 83
│ └── 207f0274383b4a79ff6d6c297e95204ba961bc [60B]
├── ee
│ └── bf02006948079f1935e19f582700f8e0acb1b5 [135B]
├── info
└── pack
Commit object type¶
The commit object contains the directory tree object hash, parent commit hash, author, committer, date and message.
Git log will show us the hash for the commit message:
$ git log
commit eebf02006948079f1935e19f582700f8e0acb1b5
Author: Matthew Brett <matthew.brett@gmail.com>
Date: Fri Feb 4 11:26:27 2022 +0000
An example commit
Note
I’ll use git cat-file
to show the contents of the hashed files in
.git/objects
, but cat-file
is a relatively obscure git command
that you will probably not need in your daily git work.
git cat-file -t
shows us the type of the object represented by a
particular hash:
$ git cat-file -t eebf02006948079f1935e19f582700f8e0acb1b5
commit
git cat-file -p
shows the contents of the file associated with this hash:
$ git cat-file -p eebf02006948079f1935e19f582700f8e0acb1b5
tree 83207f0274383b4a79ff6d6c297e95204ba961bc
author Matthew Brett <matthew.brett@gmail.com> 1643973987 +0000
committer Matthew Brett <matthew.brett@gmail.com> 1643973987 +0000
An example commit
Tree object type¶
The commit contents gave us the hash of the directory listing for the commit. If we inspect this object, we find it is of type “tree” and contains the directory listing for the commit:
$ git cat-file -t 83207f0274383b4a79ff6d6c297e95204ba961bc
tree
$ git cat-file -p 83207f0274383b4a79ff6d6c297e95204ba961bc
100644 blob 2f781156939ad540b2434d012446154321e41e03 example_file.txt
The tree object contains one line per file or subdirectory, with each line giving file permissions, object type, object hash and filename. Object type is usually one of “blob” for a file or “tree” for a subdirectory 1.
Blob object type¶
The directory listing gave us the hash of the stored of example_file.txt
.
This object is of type “blob” and contains the file snapshot:
$ git cat-file -t 2f781156939ad540b2434d012446154321e41e03
blob
$ git cat-file -p 2f781156939ad540b2434d012446154321e41e03
An example file
Blob is an abbreviation for “binary large object”. When we git add
a
file such as example_file.txt
, git creates a blob object containing the
contents of the file. Blobs are therefore the git object type for storing
files.
Tag object type¶
There is also a git type for annotated tags. We don’t have one of those yet, so let’s make one:
$ git tag -a first-commit -m "Tag pointing to first commit"
This gives us a new object in .git/objects
:
objects
├── 2f
│ └── 781156939ad540b2434d012446154321e41e03 [32B]
├── 68
│ └── c63bbda2bafc9a324508263a65c177e3a22732 [146B]
├── 83
│ └── 207f0274383b4a79ff6d6c297e95204ba961bc [60B]
├── ee
│ └── bf02006948079f1935e19f582700f8e0acb1b5 [135B]
├── info
└── pack
The object is of type “tag”:
$ git cat-file -t 68c63bbda2bafc9a324508263a65c177e3a22732
tag
The tag object type contains the hash of the tagged object, the type of tagged object (usually a commit), the tag name, author, date and message:
$ git cat-file -p 68c63bbda2bafc9a324508263a65c177e3a22732
object eebf02006948079f1935e19f582700f8e0acb1b5
type commit
tag first-commit
tagger Matthew Brett <matthew.brett@gmail.com> 1643973987 +0000
Tag pointing to first commit
Notice that the “object” the tag points to, via its hash, is the commit object, as we were expecting.
Footnotes
- 1
The object types in a directory listing are almost invariably either “blob” or “tree”, but can also be “commit” for recording the commit of a git submodule - see How do git submodules work?.