Repository navigation
Git Internals
bparlaker edited this page Oct 6, 2026
·
2 revisions
Most Git confusion disappears once you see that Git is just a content-addressed key-value store plus a few pointers.
| Object | Stores | Analogy |
|---|---|---|
| blob | the contents of a file (no name!) | a page of text |
| tree | a directory listing: names → blobs/trees | a folder |
| commit | one root tree + parent(s) + author + message | a snapshot with a label |
| tag (annotated) | a named, signed pointer to a commit | a bookmark |
Every object is named by the SHA-1 hash of its content (SHA-256 is supported in newer repos). Same content ⇒ same hash ⇒ stored once.
mkdir demo && cd demo && git init
echo "hello git" > hello.txt
git add hello.txt
git commit -m "first commit"
git cat-file -t HEAD # -> commit
git cat-file -p HEAD # show the commit objectOutput (hashes will differ):
tree 07ed5a7aebb914e3a02edf6d622b82d364037e3c
author Berker Parlaker <berker@example.com> 1790680000 +0300
committer Berker Parlaker <berker@example.com> 1790680000 +0300
first commit
git cat-file -p 07ed5a7 # the tree
# 100644 blob 8d0e41234f24b6da002d962a26c2495ea16a425f hello.txt
git cat-file -p 8d0e412 # the blob
# hello gitYou can even compute a blob's hash without Git storing anything:
echo "hello git" | git hash-object --stdin
# 8d0e41234f24b6da002d962a26c2495ea16a425fEach commit points to its parent(s), so history is a directed acyclic graph:
A <-- B <-- C <-- D (main)
\
E <-- F (feature)
Changing anything in an old commit changes its hash - and therefore the hash of every commit after it. That is why history is tamper-evident, and why rewriting pushed history is disruptive.
cat .git/HEAD # ref: refs/heads/main
cat .git/refs/heads/main # 40-char commit hashA branch is a 41-byte file holding a hash. Creating a branch is therefore instant and nearly free.
-
git gcpacks objects and stores deltas, so repositories stay small even though Git conceptually stores full snapshots. - An empty folder cannot be committed - trees only list things that contain blobs. (Convention: add a
.gitkeepfile.) -
git fsckverifies every hash in the repo - corruption can't go unnoticed.
🎨 Term Project
📘 Git
🗂 Project workflow