Skip to content
GKgkml.dev
← Learn Git & GitHub

Lesson 1 of 7 · 9 min

The object model: what Git actually stores

Blobs, trees, commits and refs — the four things that explain every Git behaviour.

Four object types

A blob is file content, with no name and no metadata. A tree is a directory listing: names, modes, and pointers to blobs and other trees. A commit points to one tree — the whole project at that moment — plus parent commits, an author, a timestamp and a message. A tag object is an annotated tag with its own message and optional signature.

Every object is stored under the SHA of its content, which means identical content is stored once no matter how many commits contain it, and any change anywhere produces a different hash.

Refs: pointers with names

A branch is a file under .git/refs/heads containing one commit hash. Committing writes a new commit and moves that file to point at it. Deleting a branch deletes the pointer — the commits are still there until garbage collection.

HEAD is a pointer to the current branch, usually holding 'ref: refs/heads/main'. Detached HEAD simply means HEAD contains a commit hash directly instead of a branch name. Commits made there are unreachable once you leave, which is why the warning exists.

Looking at the model directly
git cat-file -t HEAD          # commit
git cat-file -p HEAD          # tree, parent, author, message
git cat-file -p HEAD^{tree}   # the directory listing
git rev-parse HEAD            # the commit hash

cat .git/HEAD                 # ref: refs/heads/main
cat .git/refs/heads/main      # the commit hash the branch points to

Note: Everything Git does is reading and writing these files. Nothing is hidden.

Why history is immutable

A commit's hash covers its tree, message, author, timestamp and parent hashes. Changing anything — even a message — produces a different hash, and every descendant's hash changes too because each contains its parent's.

So you never actually edit a commit. Commands like amend and rebase create new commits and move a branch pointer to them. The originals remain until garbage collection, which is exactly why recovery is possible.

Worth remembering

  • Git stores snapshots, not diffs; diffs are computed when you ask for them.
  • A commit points to a tree and to its parents, and is identified by a hash of all of it.
  • A branch is a movable pointer to a commit. That is the entire definition.

Test it now

The easy bank checks these fundamentals directly.