Branches
How branches work as cheap, movable pointers — and how to use them to isolate risky work from stable code.
What you'll learn
- What a branch really is: a movable pointer to a commit, not a copy of files
- How HEAD tracks which branch you are currently on
- How to create, switch, list, and delete branches using both modern and classic git commands
Before you start
What a branch actually is
Before touching a command, get the mental model right — it changes how everything else feels.
A branch is not a copy of your files. It is a movable pointer: a lightweight label that points to one specific commit. That is literally all it is — a 41-byte file on disk containing a SHA hash.
When you create a new commit on a branch, git does two things:
- Writes the new commit object (snapshot + parent pointer).
- Moves the branch pointer forward to that new commit.
Because creating a branch just writes one small file, it is instant regardless of how large your repository is. No files are duplicated. No folders are copied. The branch is just a name that says “right now, this label points here.”
HEAD: the pointer to your pointer
HEAD is a special pointer that tells git which branch you are currently on. When you commit, HEAD’s branch moves forward. When you switch branches, HEAD itself moves to point at a different branch.
You can think of it as: HEAD → branch → commit.
Two branches diverging from a shared history. HEAD points to feature, meaning new commits go there. main is untouched.
Both branches share the first two commits — no duplication. The history only diverges from the point where you created feature.
Creating and switching branches
The modern way (git 2.23+)
git switch -c feature/dark-mode
Switched to a new branch 'feature/dark-mode'
The -c flag means “create.” This is equivalent to two older commands run together: git branch feature/dark-mode followed by git switch feature/dark-mode.
Switch back to main at any time:
git switch main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
The classic way (still common in docs and CI scripts)
git checkout -b feature/dark-mode
checkout -b does the same thing as switch -c. You will see both in real projects. The newer switch command is preferred because it is more explicit — checkout does too many things.
Listing and deleting branches
List all local branches. The asterisk marks the one HEAD is on:
git branch
* feature/dark-mode
main
Delete a branch after you have merged it:
git branch -d feature/dark-mode
Deleted branch feature/dark-mode (was d2a9c43).
The feature-branch workflow
This is the pattern behind pull requests on GitHub, GitLab, and Bitbucket:
- Start from a clean
main— make suremainis up to date. - Create a branch —
git switch -c feature/my-thing. - Work and commit freely — make as many commits as you need. Experiment. Break things. None of it touches
main. - When the feature is ready, merge — switch back to
mainand merge (covered in the next lesson). Your commits join the main history. - Delete the branch —
git branch -d feature/my-thing. The commits still exist inmain; you are just removing the label.
What switching branches actually does
When you run git switch main, git:
- Looks at the commit that
mainpoints to. - Updates every tracked file in your working directory to match that commit’s snapshot.
- Moves HEAD to point at
main.
This is why switching is fast — git is replaying a snapshot it already has, not copying files across disk. On a large repository the checkout of files can take a moment, but the branch mechanics themselves are instantaneous.