What Are Branches?
A Git branch is nothing more than a movable pointer — a 41-byte text file living under .git/refs/heads/ — that holds the SHA-1 hash of a single commit. When you make a new commit while a branch is checked out, Git updates that pointer to reference the new commit, and the previous commit becomes the new commit's parent. This design is dramatically lighter weight than the branching model in older systems like Subversion, where branching meant physically copying an entire directory tree on the server. Creating a Git branch is an near-instant, constant-time operation regardless of repository size, because it only ever writes a single small file.
Cricket analogy: A Git branch is like a scoreboard's 'current batsman' marker, just a small pointer to whoever is on strike, not a duplicate of the whole stadium; updating it after each run is instant, unlike physically resetting an entire ground the way old-school systems required full copies.
HEAD and the currently checked-out branch
HEAD is a special pointer that tells Git which branch (or, in a 'detached HEAD' state, which specific commit) you currently have checked out. Ordinarily HEAD doesn't point directly at a commit; it points at a branch ref, which in turn points at a commit — a pointer to a pointer. This indirection is exactly what lets git commit know which branch's tip to advance. Running cat .git/HEAD in most repositories shows something like ref: refs/heads/main, confirming that HEAD is simply following the main branch.
Cricket analogy: HEAD is like the umpire's signal indicating which end is currently in play; it usually points to 'the bowling end' (the branch), which itself points to who's actually bowling (the commit) — a pointer to a pointer — except in a 'detached' rain-delay scenario where play is fixed on one specific delivery.
Why branches are cheap in Git
Because a branch is just a reference and not a copy of files, creating dozens of branches costs almost nothing in disk space or time — the actual commit objects, trees, and blobs they point to are shared across all branches until history diverges. This cheapness is precisely why Git-centric workflows (feature branching, trunk-based development, git-flow) encourage developers to branch liberally for nearly every piece of work, something that would have been far more expensive with centralized version control systems.
Cricket analogy: Because a branch is just a pointer sharing the same underlying overs already bowled, a captain can declare dozens of tactical 'what-if' net sessions at almost no cost, encouraging liberal experimentation the way a full replayed match would never have allowed under older scoring systems.
# List all local branches, with * marking the current one
$ git branch
* main
feature/search-autocomplete
# Show what each branch pointer references
$ git rev-parse main feature/search-autocomplete
7d6e5f4c9b2a1e3d8f0c6b4a2e1d9f8c7b6a5e4d
9f8e7d6c5b4a3e2d1f0c9b8a7e6d5c4b3a2e1d9f
# Confirm HEAD is following main via a symbolic reference
$ cat .git/HEAD
ref: refs/heads/main
# Create a branch without switching to it
$ git branch feature/payment-refundsA helpful mental model: think of commits as an immutable, growing chain of snapshots, and branches as sticky notes you can move between any commits in that chain to mark 'this is where feature X currently stands.' Moving a sticky note costs nothing — the underlying chain of snapshots is untouched.
Deleting a branch with git branch -d <name> only removes the pointer, not the commits it referenced, provided they are still reachable from another branch — but git branch -D (force delete) can silently orphan commits that are reachable from nowhere else, making them eligible for garbage collection.
- A branch is a lightweight, movable pointer to a single commit, stored as a small file under
.git/refs/heads/. - HEAD normally points at the current branch, which in turn points at a commit — an indirection that lets
git commitknow which ref to advance. - Because branches don't copy files, creating and switching branches is a fast, constant-time operation in Git.
- Multiple branches can point at commits that share the same underlying history, since commits are immutable and content-addressed.
git branchlists local branches; the asterisk marks the currently checked-out one.- Deleting a branch removes only the pointer; the commits remain until they become unreachable and are garbage collected.
Practice what you learned
1. What does a Git branch actually store?
2. What does HEAD normally point to?
3. Why is branch creation in Git considered inexpensive?
4. What happens to a branch's commits when you run `git branch -d` on it after it has been fully merged elsewhere?
5. Where does Git store a local branch reference on disk?
Was this page helpful?
You May Also Like
Creating and Switching Branches
Master the day-to-day commands for creating, switching, listing, and deleting branches, including the modern git switch/git restore split from git checkout.
Merging Branches
Understand how git merge combines diverged branch histories, the difference between fast-forward and three-way merges, and when each occurs.
The Git Object Model
A deep dive into how Git stores data internally as blobs, trees, commits, and tags — the content-addressable database underlying every Git operation.
Feature Branch Workflow
A widely used team workflow where every change lives on its own short-lived branch off main, gets reviewed via pull request, and is merged once approved and tested.
Related Reading
Related Study Notes in Software Engineering
Browse all study notesMicroservices Study Notes
Software Architecture · 30 topics
Software EngineeringTesting & TDD Study Notes
Software Testing · 30 topics
Software EngineeringDesign Patterns Study Notes
Software Design · 30 topics
Software EngineeringSoftware Engineering Study Notes
Python · 40 topics
Software EngineeringSystem Design Study Notes
Architecture · 40 topics