Most developers use Git every day without understanding what happens beneath git commit. That gap is responsible for a huge amount of confusion around rebases, detached HEADs, and merge conflicts. Let us fix it once and for all.
The Four Git Object Types
Git stores everything in .git/objects/ as one of four immutable object types. Each object is identified by the SHA-1 hash of its own content — so the same content always produces the same hash.
- blob — raw file content. Filename and permissions are not stored here.
- tree — a directory snapshot: a list of filenames → blob or tree SHAs.
- commit — a pointer to a tree, your message, author, timestamp, and parent commit SHA(s).
- tag — a human-readable name pointing to a specific commit (used for releases).
# Inspect any Git object by its hash
$ git cat-file -t 5b4f3a2 # → "commit"
$ git cat-file -p 5b4f3a2 # → commit contents
# Read a blob (raw file content)
$ git cat-file -p HEAD:README.md
What git commit Does, Step by Step
- Git takes each modified file from the staging area and hashes its content into a new blob object.
- It builds a tree object representing the entire current directory structure, pointing to the blobs.
- It creates a commit object containing your message, author details, timestamp, and the SHA of the parent commit.
- It updates the current branch reference — just a tiny text file at
.git/refs/heads/main— to point at the new commit SHA.
main ──→ commit c3 ──→ tree t3 ──→ blob b1 (main.py)
│ └──→ blob b2 (README.md)
└──→ parent: commit c2 ──→ tree t2 ──→ ...
Why Branches Are Cheap
A branch in Git is nothing more than a text file containing a 40-character SHA. Creating a branch does not copy any files — it just writes a new 40-byte file. That is why branching in Git is instant, regardless of repo size, whereas branching in SVN could take minutes.
"A branch is a lightweight movable pointer to a commit." — Pro Git, Scott Chacon
Detached HEAD Explained
Normally, HEAD is a symbolic reference pointing to a branch name (e.g. main), which then points to a commit. When you git checkout <sha> directly, HEAD points at the commit itself — that is a detached HEAD. Any commits you make here are not reachable from any branch and will eventually be garbage collected.