How does Git store data internally with blobs, trees, and commits?
Explore Git's internal object model — how blobs hold file content, trees map directories, and commits snapshot your project via content-addressed hashes.
Expected Interview Answer
Git stores everything as content-addressed objects in a key-value store: blobs hold file contents, trees represent directories linking names to blobs and sub-trees, and commits point to a top-level tree plus parent commits and metadata. Each object is identified by the SHA-1 (or SHA-256) hash of its content.
A blob is just the raw bytes of a file, with no filename. A tree maps names to entries — each entry is a mode, a type, a hash, and a name — pointing to blobs (files) or other trees (subdirectories), so a tree snapshots a whole directory structure. A commit references exactly one root tree (the full project snapshot), zero or more parent commits, an author/committer, timestamp, and message. Because objects are named by their content hash, identical content is stored once and any change produces a new hash, making the history an immutable, tamper-evident chain.
- Deduplication — identical file content is stored only once by hash
- Integrity — content-addressing detects any corruption or tampering
- Cheap snapshots — unchanged trees and blobs are reused across commits
- Fast comparisons — comparing hashes reveals what changed
- Immutable history — commits form a verifiable chain via parent links
AI Mentor Explanation
Picture a club archive where each individual scorecard is filed by a fingerprint of its contents (a blob), each match folder lists which scorecards belong to it (a tree), and each season ledger records the folder for a given day plus a link to the previous day's ledger (a commit). Two identical scorecards share one fingerprint and are filed once, and the linked ledgers form an unbreakable timeline.
Step-by-Step Explanation
Step 1
Content becomes a blob
Git compresses a file's raw bytes, hashes them, and stores the result as a blob object named by that hash — no filename attached.
Step 2
Directories become trees
A tree object lists entries (mode, type, hash, name) pointing to blobs and sub-trees, capturing one directory's structure.
Step 3
A snapshot is a root tree
The top-level tree references all sub-trees and blobs, representing the entire project at one moment.
Step 4
A commit wraps the snapshot
A commit object points to that root tree, lists parent commit hashes, and adds author, committer, timestamp, and message.
Step 5
Hashes chain the history
Each object's hash comes from its content, so parents link commits into an immutable, verifiable chain; refs like branches just point to a commit hash.
What Interviewer Expects
- Blob = file content, tree = directory, commit = snapshot + metadata
- Objects are content-addressed by their hash
- A commit points to one root tree and its parent commit(s)
- Identical content is deduplicated; changes create new objects
- How this enables integrity and cheap branching
- Awareness that Git snapshots state rather than storing diffs
Common Mistakes
- Saying Git stores diffs/deltas per commit instead of full snapshots
- Thinking a blob stores the filename (the tree stores names)
- Confusing a commit with the tree it points to
- Believing each commit copies every file even when unchanged
- Assuming branches are heavy objects rather than pointers to a commit hash
Best Answer (HR Friendly)
“Internally Git is a simple database of objects identified by a fingerprint of their contents. Files are stored as blobs, folders as trees that list what's inside them, and each commit is a snapshot that points to the top folder plus the commit before it — which is why history is reliable and unchanged files are never duplicated.”
Code Example
# Create a blob from content and see its hash
echo 'hello' | git hash-object -w --stdin
# -> ce013625030ba8dba906f756967f9e9ca394464a
# Show the type and content of any object
git cat-file -t ce01362 # blob
git cat-file -p ce01362 # hello
# Look at the tree a commit points to
git cat-file -p HEAD^{tree}
# 100644 blob a1b2c3d... README.md
# 040000 tree e4f5g6h... src
# Show the commit object itself (tree, parent, author, message)
git cat-file -p HEADFollow-up Questions
- Does Git store diffs or full snapshots — and how do packfiles fit in?
- How does content-addressing guarantee integrity?
- What is the difference between a tree and a commit?
- How are branches and tags represented internally?
- Why did Git begin moving from SHA-1 to SHA-256?
MCQ Practice
1. Which Git object stores the raw contents of a file?
A blob holds the compressed file contents only — the filename is recorded by the tree that references the blob.
2. What does a commit object point to as its snapshot of the project?
A commit references exactly one top-level (root) tree, which in turn references all sub-trees and blobs of the snapshot.
3. How does Git avoid storing the same unchanged file twice across commits?
Because objects are named by a hash of their content, identical content maps to the same blob and is stored only once.
Flash Cards
What is a blob? — A Git object holding the compressed raw contents of a file, named by the hash of that content — with no filename.
What is a tree? — A Git object representing a directory: a list of entries (mode, type, hash, name) pointing to blobs and sub-trees.
What is a commit? — An object pointing to one root tree (the snapshot), zero or more parent commits, plus author, timestamp, and message.
Why is Git history tamper-evident? — Every object is named by a hash of its content, so any change alters the hash and breaks the parent chain unless re-created.