Skip to content

Git Objects

A library of immutable snapshots: Git objects are like a library of sealed time capsules — each commit, file, and directory is stored as an immutable object identified by its content hash. Nothing is ever truly deleted; old versions remain accessible through the object graph.

Why it matters: Understanding Git objects explains why git checkout is instant (it just moves a pointer), why git rebase rewrites history (it creates new objects), and why .git can grow large (old objects accumulate).

The key insight: Git stores snapshots, not diffs — each commit points to a complete tree of files. Diffs are computed on demand, not stored. This makes operations like checkout and branch switching O(1) regardless of history size.

At its core, Git is a content-addressable filesystem. It stores data as objects, each identified by the SHA-1 hash of its content. This is not a version control feature — it is the fundamental storage mechanism. Version control is built on top of it.

There are four types of Git objects:

TypePurposeContains
blobFile contentRaw file bytes (no filename, no metadata)
treeDirectory listingList of (mode, name, SHA-1) entries (blobs or subtrees)
commitSnapshot metadataTree SHA-1, parent commit(s), author, committer, message, timestamp
tagAnnotated tagTag name, tagger, message, target commit SHA-1, optional GPG signature

Every object is stored as a compressed file under .git/objects/Named by its SHA-1 hash. For example, an object with hash a3f2b1c... is stored at .git/objects/a3/f2b1c....

flowchart LR
    A["File content<br/>or tree structure"] --> B["git hash-object -w<br/>or git write-tree"]
    B --> C["Compressed object<br/>.git/objects/XX/YY..."]
    C --> D["SHA-1 hash returned"]
    D --> E["Referenced by<br/>tree or commit"]
    E --> F["Reachable from<br/>a branch or tag"]

    style A fill:#fff3e0
    style C fill:#e8f5e9
    style F fill:#e3f2fd

A blob is the simplest Git object. It stores the raw content of a file — nothing more. It does not store the filename, permissions, or any metadata. Two files with identical content at different paths produce the same blob object.

Terminal window
## Create a blob from a file"s content and print its hash
$ echo "Hello, World" | git hash-object -w --stdin
ce013625030ba8dba906f756967f9e9ca394464a
## Verify the object exists
$ git cat-file -t ce013625030ba8dba906f756967f9e9ca394464a
blob
# Print the blob's content
$ git cat-file -p ce013625030ba8dba906f756967f9e9ca394464a
Hello, World

The hash is computed over the concatenation of the object header and the content:

blob <content-length>\0<content>

For "Hello, World\n" (13 bytes):

blob 13\0Hello, World

The SHA-1 of this byte sequence is ce013625030ba8dba906f756967f9e9ca394464a.

  • References: Covers Git refs including branches and tags that point to commit objects.
  • The Three Trees: Explains the working directory, staging area, and repository where objects are stored.
  • Branching: Branch creation and management that relies on the commit object model.