C.W.K.
Stream
Lesson 02 of 05 · published

Snapshots, Not Patches

~20 min · snapshots, objects

Level 0Untracked Rookie
0 XP0/47 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

Snapshots, not patches

The most common wrong intuition about Git is that it stores diffs — the difference between version N and N+1. That is how SVN and CVS work. Git does something fundamentally different: every commit is a complete snapshot of every file, addressed by hash.

If a file did not change between two commits, Git does not store it twice. It stores a pointer to the same blob. Identical content always produces the same hash, so deduplication is automatic. Any one-bit change produces a completely different hash, so corruption is detectable. This is the whole reason Git is fast on history operations: showing you any version is just loading the snapshot, not replaying every diff since the dawn of the project.

Three object types make this work. A blob is the raw bytes of one file. A tree is a directory listing — names, modes, and the blob hashes they point to. A commit is a small object holding tree hash, parent hash(es), author, committer, and message. Each object lives in .git/objects/, named by its SHA-1 hash. Branches are 41 bytes pointing at a commit. Tags are 41 bytes pointing at any object. The whole graph is content-addressable.

You will not type git cat-file every day, but seeing one blob, one tree, and one commit by hand is the vaccine against the diff-based mental model. Once you have looked, branches stop being magical and merges stop being scary.

Code

Peek at one commit's actual objects·bash
# Most recent commit hash
HASH=$(git rev-parse HEAD)

# Show the commit object (tree + parent + message)
git cat-file -p $HASH

# That commit points to a tree — list it
TREE=$(git cat-file -p $HASH | head -1 | awk '{print $2}')
git cat-file -p $TREE

# Each entry in the tree is a (mode, type, hash, name) tuple
Identical files only stored once·bash
# Create two identical files in fresh dirs and let Git hash them.
echo 'hello' > a.txt
git hash-object a.txt
echo 'hello' > b.txt
git hash-object b.txt
# Both print the SAME hash — Git would store one blob, two tree entries.

External links

Exercise

In any small repo, run git rev-parse HEAD, then git cat-file -p <hash> on the result. Follow the tree pointer with another git cat-file -p. Pick one blob hash and run git cat-file -p <blob> on it. Note three concrete things about the output that would make sense only in a snapshot model and would not in a diff model.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.