The four fundamental object types (blob, tree, commit, tag)
In Git, there are four fundamental object types that form the core of version control: blob
, tree
, commit
, and tag
. These objects are interconnected through hash values, creating the data structure of a Git repository. Understanding their roles and relationships is key to mastering how Git works.
blob Objects
A blob
(Binary Large Object) is the most basic data unit in Git, used to store file content. It contains no metadata (such as filenames or permissions), only the raw data of the file. Every time file content changes, Git generates a new blob
object.
For example, a file named example.txt
with the content Hello, Git!
can have its corresponding blob
object viewed using the following command:
echo 'Hello, Git!' | git hash-object --stdin
The output might look like:
8ab686eafeb1f44702738c8b0f24f2567c36da6d
The hash value of a blob
object is calculated from the file content and header information (such as blob
and file size). If the file contents are identical, even if the filenames differ, their blob
hash values will be the same.
tree Objects
A tree
object is analogous to a directory in a file system. It records the references to blob
and other tree
objects, along with metadata like filenames and permissions. A tree
object can contain multiple entries, each pointing to a blob
or sub-tree
.
For example, here’s a simplified representation of a tree
object:
100644 blob 8ab686eafeb1f44702738c8b0f24f2567c36da6d example.txt
040000 tree 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a subdir
The hash value of a tree
object is generated from the content of all its entries. When the directory structure or file permissions change, the corresponding tree
object is updated.
commit Objects
A commit
object is a node in Git’s version history. It points to a tree
object (representing the project snapshot) and includes references to the author, committer, commit message, and parent commit(s). Each commit generates a new commit
object.
A typical commit
object looks like this:
tree 92b8b6ffb5f1a1a7a6b5d9c9d8e8f7b6c5b4a3a2
parent 6a1a7b8c9d0e1f2g3h4i5j6k7l8m9n0o1p2q3r4s
author John Doe <john@example.com> 1625097600 +0800
committer Jane Smith <jane@example.com> 1625097600 +0800
Initial commit
The hash value of a commit
object is calculated from all the above information. By referencing parent commits, Git builds a complete version history graph.
tag Objects
A tag
object is a special reference, often used to mark specific commit
objects (e.g., for releases). Unlike lightweight tags (which directly point to a commit
), annotated tags create an independent tag
object containing the tag name, tag message, tag creator, and a reference to the target commit
.
An example tag
object:
object 6a1a7b8c9d0e1f2g3h4i5j6k7l8m9n0o1p2q3r4s
type commit
tag v1.0.0
tagger John Doe <john@example.com> 1625097600 +0800
Release version 1.0.0
The hash value of a tag
object is also generated from its content. Annotated tags provide richer metadata and are suitable for formal version marking.
Relationships Between Objects
These four object types are interconnected through hash values, forming a Directed Acyclic Graph (DAG). For example:
- A
commit
points to atree
; - The
tree
may contain entries pointing toblob
(file content) and othertree
(subdirectories); - Another
commit
may point to the sametree
(if files are unchanged) or a newtree
; - A
tag
object points to a specificcommit
.
You can inspect the content of objects using low-level commands:
git cat-file -p <hash>
Practical Example Analysis
Consider a simple project with the following commit history:
- Create
README.md
(content:# Project
); - Create
src/index.js
(content:console.log('Hello')
); - Commit and tag as
v1.0.0
.
The corresponding object relationships might be:
blob
A:# Project
(content ofREADME.md
);blob
B:console.log('Hello')
(content ofsrc/index.js
);tree
X: containsblob
A (README.md
) andtree
Y (src/
directory);tree
Y: containsblob
B (index.js
);commit
C: points totree
X;tag
T: points tocommit
C.
Object Storage Mechanism
Git stores all objects in the .git/objects
directory. The first two characters of the hash are used as the subdirectory name, and the rest as the filename. For example, an object with the hash 8ab686...
is stored at:
.git/objects/8a/b686eafeb1f44702738c8b0f24f2567c36da6d
Objects are stored in a compressed format by default and can be decompressed using zlib
to view the raw content. This design saves space while ensuring data integrity—any change to the content alters the hash value.
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn