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).
BASH
# 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

  1. Git takes each modified file from the staging area and hashes its content into a new blob object.
  2. It builds a tree object representing the entire current directory structure, pointing to the blobs.
  3. It creates a commit object containing your message, author details, timestamp, and the SHA of the parent commit.
  4. It updates the current branch reference — just a tiny text file at .git/refs/heads/main — to point at the new commit SHA.
OBJECT GRAPH
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.