How Git Works Internally

Under its commands, Git is a tiny content-addressable database of four object types — blobs, trees, commits, and tags — every one keyed by a hash. Once you see the object model, refs, HEAD, and the commit DAG, everything else (amend, rebase, why commits are immutable) suddenly makes sense. This lesson opens the hood.

Learn How Git Works Internally in our free Git course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free Git course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

1️⃣ The Object Model

Everything in Git is one of four objects, each keyed by a hash. A blob is the bytes of one file; a tree is a directory mapping names to blobs and sub-trees; a commit is a snapshot pointing at a root tree plus parent(s), author, and message; a tag is an annotated pointer to (usually) a commit. A commit points to a tree, which points to blobs.

2️⃣ Content-Addressable Storage

Git stores objects under a hash of their content ( SHA-1 , or SHA-256 in newer repos), in .git/objects . git hash-object shows the id Git would give content, and git cat-file -p pretty-prints any object. Identical content always hashes the same — that's how Git deduplicates.

3️⃣ Refs, HEAD & the Commit DAG

Branches and HEAD are just refs — small files holding a commit id. A branch ref under .git/refs/heads points to a commit; HEAD usually points to the current branch. Because each commit records its parent , commits form a Directed Acyclic Graph (DAG): the shape of your history.

4️⃣ Why Commits Are Immutable

A commit's id is a hash of its content — tree, parent(s), author, message. Change one byte of a file and the blob hash changes, so the tree hash changes, so the commit hash changes. The old commit still exists, untouched, with its original id. Nothing is edited in place — which is precisely why amend and rebase create new commits.

Your turn. Walk from HEAD down toward a file's bytes and hash content yourself. Fill in the two blanks.

📋 Quick Reference

No commands given this time — just the plan. Walk from a commit all the way down to raw file bytes.

Practice quiz

Which Git object stores the raw contents of a single file?

  • A blob
  • A tree
  • A commit
  • A tag

Answer: A blob. A blob holds file contents only — no name and no metadata; the filename is recorded by the tree that points to it.

Which object represents a directory, mapping names to blobs and other trees?

  • A commit
  • A blob
  • A tree
  • A ref

Answer: A tree. A tree lists entries (name + mode + object id) pointing at blobs (files) and sub-trees (subdirectories).

What does a commit object contain?

  • Only the file contents
  • A top tree, parent commit(s), author/committer, and a message
  • Just a branch name
  • A list of remotes

Answer: A top tree, parent commit(s), author/committer, and a message. A commit references the root tree (a full snapshot), its parent(s), author and committer info, and the message.

Every Git object is identified by...

  • Its filename
  • A random UUID
  • A timestamp
  • A hash of its content (SHA-1, or SHA-256 in newer repos)

Answer: A hash of its content (SHA-1, or SHA-256 in newer repos). Git is content-addressable: an object's id is the hash of its contents, so identical content yields the same id.

In which directory does Git keep its objects?

  • .git/objects
  • .git/refs
  • .git/hooks
  • .git/index

Answer: .git/objects. Loose and packed objects live under .git/objects, addressed by their hash.

Which command pretty-prints the content of an object by its hash?

  • git show-object
  • git cat-file -p <hash>
  • git read <hash>
  • git print

Answer: git cat-file -p <hash>. git cat-file -p <hash> pretty-prints any object — blob, tree, commit, or tag.

Which command computes the object id Git would give a piece of content?

  • git rev-parse
  • git id
  • git checksum
  • git hash-object

Answer: git hash-object. git hash-object reads content and prints the hash Git would store it under (with -w it also writes the object).

What is a branch, at the object level?

  • A copy of all the files
  • A separate object database
  • A ref: a movable pointer to a commit
  • A type of tag that can't move

Answer: A ref: a movable pointer to a commit. A branch is just a ref under .git/refs/heads holding the id of the commit it currently points to.

What does HEAD usually point to?

  • The root tree
  • The current branch (which in turn points to a commit)
  • The remote
  • The staging area

Answer: The current branch (which in turn points to a commit). HEAD is normally a symbolic ref naming your current branch; following it leads to the checked-out commit.

Why are commits effectively immutable?

  • Because a commit's id is a hash of its content, so changing anything produces a different id and a new commit
  • Because the OS forbids edits
  • They are stored on read-only disks
  • Git locks the files

Answer: Because a commit's id is a hash of its content, so changing anything produces a different id and a new commit. Since the hash is derived from the content (including parent and tree), any change yields a new object with a new id rather than mutating the original.