Stage 2 · Tools
Branching & Merging
Creating Branches
Branches are lightweight pointers to commits — learn to create, switch, and understand how they share history.
What Is a Branch?
A branch in Git is not a copy of your code. It is a lightweight, movable pointer to a commit. When you create a branch, Git writes a new 40-byte file containing the SHA hash of the commit it points to. That is it — no files are copied, no directories are created.
Because branches are just pointers, creating one is nearly instant regardless of repository size. This is fundamentally different from older version control systems like SVN, where branching meant copying entire directory trees.
A branch is a 40-byte file containing a commit hash. Creating a branch does not duplicate your working tree — it just adds a new label pointing to the current commit.
Creating Your First Branch
The git branch command creates a new branch at the current commit. It does not switch to the new branch — it only creates the pointer.
# See which branch you are on
git branch
# Create a new branch called feature/login
git branch feature/login
# List all branches
git branch -aThe git branch command without arguments lists local branches. The currently active branch is marked with an asterisk. The -a flag shows all branches including remote-tracking branches.
After creating the branch, both main and feature/login point to the same commit. The commit history is shared — branches diverge only when new commits are made on one of them.
Switching Branches
Git provides the git switch command (introduced in Git 2.23) as the modern way to switch branches. The older git checkout command also works but mixes branch switching with file restoration, which can be confusing.
# Modern approach (Git 2.23+)
git switch feature/login
# Legacy approach (still works everywhere)
git checkout feature/loginBoth commands update HEAD to point to the target branch and update your working tree to match that branch's snapshot. git switch is more focused and produces clearer error messages.
| Command | Purpose | Risk Level |
|---|---|---|
| git switch <branch> | Switch branches only | Safe — refuses if you have uncommitted changes |
| git checkout <branch> | Switch branches + restore files | Confusing — same command does two things |
| git checkout -- <file> | Restore a single file | Destructive — discards changes without confirmation |
Prefer git switch over git checkout for switching branches. It does exactly one thing and gives clear errors when your working tree has uncommitted changes.
Create and Switch in One Step
Most of the time you want to create a branch and immediately start working on it. The -c flag on git switch (or -b on git checkout) does both in a single command.
# Modern approach — create and switch
git switch -c feature/dashboard
# You are now on feature/dashboard with one commit of history
git log --oneline
# a1b2c3d (HEAD -> feature/dashboard) Add dashboard layout
# f4e5d6c (main) Initial commitThe -c flag creates a new branch and immediately switches to it. This is the most common way to start new work in Git.
If you need to branch from a specific commit or branch, pass a starting point as the last argument.
# Create from a specific commit
git switch -c hotfix/crash v2.1.0
# Create from a remote branch
git switch -c fix/typo origin/mainBranching from a specific commit is useful for hotfixes that need to diverge from a release tag, or when starting work based on the latest remote state.
The HEAD Pointer
HEAD is a special reference that points to the currently checked-out branch. When you make a new commit, HEAD moves forward with it. Understanding HEAD is essential for commands like git reset, git checkout, and git switch.
# What does HEAD point to?
cat .git/HEAD
# ref: refs/heads/main
# Show HEAD's current commit
git rev-parse HEAD
# a1b2c3d4e5f6...
# Symbolic reference
git symbolic-ref HEAD
# refs/heads/mainHEAD normally contains a symbolic reference to a branch (e.g., refs/heads/main). When you switch branches, Git updates this file to point to the new branch.
If you git checkout <commit-hash> instead of a branch name, HEAD points directly to a commit. This is called 'detached HEAD' — you can still make commits, but they won't belong to any branch and may be lost. Always switch back to a branch before leaving.
How Branches Share History
When you create a branch from main, both branches share the same commit history up to that point. Commits made on the new branch are only visible on that branch. Commits made on main are only visible on main. History diverges from the point where the branch was created.
# Create a feature branch
git switch -c feature/search
# Make two commits on the feature branch
echo "Search component" > search.ts
git add search.ts && git commit -m "Add search component"
echo "Search tests" > search.test.ts
git add search.test.ts && git commit -m "Add search tests"
# Switch back to main and make a commit
git switch main
echo "Bug fix" > bugfix.ts
git add bugfix.ts && git commit -m "Fix login bug"
# View the diverged history
git log --oneline --graph --allThe --graph flag draws an ASCII graph showing how branches diverge and converge. This is the clearest way to visualize branch topology.
* d4e5f6g (main) Fix login bug
| * a1b2c3d (HEAD -> feature/search) Add search tests
| * 7h8i9j0 Add search component
|/
* f4e5d6c Initial commitThe graph shows both branches diverging from f4e5d6c. The feature branch has two commits that main does not, and main has one commit that the feature branch does not.
Because branches are just pointers, you should create them freely. Short-lived branches for every feature, bugfix, or experiment keep your main branch clean and make code review easier.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.