open atlas
↑ Back to track
Git, from zero to senior GIT · 03 · 01

Branches are pointers

A git branch is just a 41-byte file under .git/refs/heads/ — a movable pointer to one commit. HEAD points at the current branch. That is why creating a branch is O(1) and cheap, unlike systems that copy whole working directories.

GIT Junior ◷ 15 min
Level
FoundationsJuniorMiddleSenior

People talk about git branches as if each one were a heavy copy of the whole project — so they hesitate to make them, the way you would hesitate to duplicate a 2 GB folder. The truth is almost comically small: a branch in git is a single text file containing one 40-character commit ID. Making a branch writes 41 bytes. That is the entire cost.

By the end of this lesson you will be able to say exactly what a branch is on disk, what HEAD points at, and why a commit “moves” a branch forward instead of copying anything.

Goal

After this lesson you can explain that a branch is a movable pointer (a ref) to a commit stored as a file under .git/refs/heads/, describe the HEAD → branch → commit chain, and say why creating a branch and committing on it are both cheap, constant-time operations.

1

A branch is a named, movable pointer to one commit — nothing more. Git stores it as a tiny file. List your branches with:

git branch
# * main
#   feature-login

The * marks the branch you are currently on. Each of those names corresponds to a file on disk. Look directly:

cat .git/refs/heads/main
# 9d1f7a3c2b8e4a6f0c1d2e3f4a5b6c7d8e9f0a1b

That 40-character hex string is the commit ID the branch points to. The whole branch is that one line. main is not special to git — it is just the conventional name of the default branch a fresh repo starts on (older repos used master).

2

Committing moves the current branch pointer forward; it never copies the branch. When you make a commit, git writes the new commit object, then rewrites the current branch file to hold the new commit’s ID. The old commit is still there — the new one records it as its parent. So a branch is always the tip of a chain that reaches back through history:

git commit -m "Add login form"
# main now points at the new commit;
# the new commit's parent is the previous tip

Nothing about the other branches changed. Only the file for the branch you were on got a new 40-character string written into it.

3

HEAD is a pointer to the current branch — a pointer to a pointer. Git needs to know which branch “you are on” so a commit knows which file to advance. That is HEAD. Normally it does not point at a commit directly; it points at a branch name:

cat .git/HEAD
# ref: refs/heads/main

Read that as a chain: HEAD → main → commit 9d1f7a3…. When you switch branches, only HEAD changes — it is repointed to the other branch’s file. When you commit, HEAD tells git which branch file to move. Two levels of indirection, both just text.

Why this works

This indirection is why git branching is cheap while older systems were not. In tools that branched by copying the working tree (or a server-side path), a branch cost time and disk proportional to the project size. In git, the commits already exist as shared, immutable objects; a branch only adds a name pointing into that existing graph. Creating a branch is O(1) — one small file — no matter whether the repo is 10 files or 100,000.

4

“Detached HEAD” is when HEAD points straight at a commit, skipping the branch level. If you check out a specific commit instead of a branch, HEAD holds a commit ID directly rather than a ref: refs/heads/… line:

git checkout 9d1f7a3
# You are in 'detached HEAD' state.
cat .git/HEAD
# 9d1f7a3c2b8e4a6f0c1d2e3f4a5b6c7d8e9f0a1b

You can look around and even commit, but those commits belong to no branch — switch away and they become unreachable (eventually garbage-collected). It is useful for inspecting old states, dangerous for new work. You will see how to enter and leave this state deliberately in the next lesson.

Worked example

Watching the pointers move.

Start on main, pointing at commit A. So HEAD → main → A.

Create a branch and stay put:

git branch feature

Now two files under .git/refs/heads/main and feature — both contain A’s ID. HEAD still points at main. No commits were copied; you just added one 41-byte file.

Switch to it and commit:

git switch feature
git commit -m "Start feature"   # creates commit B, parent A

HEAD → feature → B, and B’s parent is A. The main file is untouched — it still holds A. The two branches have now diverged: main at A, feature at B. Everything that happened was: one new commit object written, and the four bytes-ish of the feature file rewritten from A’s ID to B’s ID. That is the whole machinery of branching.

Common mistake

A common confusion: “if I delete a branch, do I lose those commits?” Deleting a branch only removes the pointer — the commit objects stay in the object store as long as something else can reach them (another branch, a tag, or your reflog). Deleting feature after merging it into main loses nothing, because main can still reach those commits. Deleting an unmerged branch is what git warns you about, because then the pointer was the only way back to that work.

Check yourself
Quiz

What physically happens on disk when you create a new branch in git?

Recap

A branch is a movable pointer to a single commit, stored as a 41-byte file under .git/refs/heads/ — that small file is the branch. HEAD is a pointer to the current branch (ref: refs/heads/main), forming the chain HEAD → branch → commit. Committing advances the current branch’s file to the new commit; nothing is copied, so creating a branch and committing are both cheap, constant-time operations. When HEAD points straight at a commit instead of a branch, you are in detached HEAD — fine for looking, risky for new work. Next you will learn the commands that create these pointers and move HEAD between them: git switch and git branch.

Practice

Start at the top. Tasks go easiest → hardest: recall a fact, apply it to a case, then a senior-level stretch. Open one, attempt it, then reveal.

recallapplystretch0 of 4 done

Something unclear?

Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.

shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.