Branching and Merging
By the end of this lesson you'll be able to spin up an isolated branch to build a feature, switch between lines of work, merge them back, and clean up — the core skill that turns Git from "save button" into real team collaboration.
Learn Branching and Merging in our free Git course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Git course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn
1️⃣ Why Branches Exist
A branch is just a movable label that points at a commit. That's it — Git copies no files when you branch, it simply writes one new pointer, so creating a branch is instant even in a huge project. The point of a branch is isolation : you can build a half-finished feature, break things, and experiment freely without ever putting the shared main branch at risk. When the work is good you merge it back; if it's a dead end you throw the branch away and lose nothing else.
Your turn. Start a new feature on its own branch, prove you're on it, and make a commit. Fill in the three blanks marked ___ using the hints in the comments.
2️⃣ HEAD — "You Are Here"
HEAD is Git's "you are here" marker. Nearly always it points at the branch you're currently on, and that branch points at your latest commit — so HEAD → main → a1b2c3d . When you switch branches, HEAD simply moves to point at the other branch. It's a label tracking your position, not a separate copy of your code.
3️⃣ Merging Branches
Merging brings the commits from one branch into another. First switch to the branch you want to receive the work, then run git merge with the branch you want to pull in. Git picks one of two strategies automatically. A fast-forward happens when main hasn't moved since the branch split off — Git just slides the main label forward and history stays perfectly linear. A three-way merge happens when both branches gained commits — Git can't slide the label, so it builds a new merge commit with two parents to tie the lines of history together.
4️⃣ Deleting Merged Branches
Once a branch is merged, its commits live safely on the branch you merged into, so the branch label has done its job. Delete it with git branch -d name — the lower-case -d is the safe delete: Git refuses if the branch isn't fully merged, protecting you from losing commits. The capital -D is the force delete — it throws the branch away even if its work was never merged, so reach for it only when you genuinely want to discard that experiment.
Now put the whole loop together: switch to main , merge your finished feature, and safely delete it. Fill in the three blanks.
5️⃣ Visualising Your History
Reading branches as plain text gets confusing fast. One command draws your entire repository as an ASCII graph — every branch, every merge, every commit — right in the terminal. Learn this early; it's the fastest way to build a mental picture of what your branches are doing.
6️⃣ Rebase vs Merge
git rebase replays your commits on top of another branch for a clean, linear history instead of a merge commit. It's powerful but dangerous on shared branches. Follow the golden rule: never rebase commits you've already pushed , because rebasing rewrites history and breaks anyone who already pulled it.
7️⃣ git stash — Quick Save
git stash temporarily shelves your uncommitted changes so you can switch branches with a clean working directory. When you come back, git stash pop restores everything exactly as it was — perfect for when an urgent bug interrupts your half-finished feature.
Common Errors (and the fix)
- "error: Your local changes to the following files would be overwritten by checkout": you tried to switch branches with uncommitted changes that clash. Either git commit the work first, or shelve it with git stash , switch, and git stash pop later.
- "error: The branch 'experiment' is not fully merged": git branch -d is protecting you — that branch has commits not on your current branch. Merge it first, or if you really want to discard the work use the capital git branch -D experiment .
- Confusing a branch with a commit: a branch is a moving label ; a commit is a fixed snapshot . git branch x doesn't save your files — only git commit does. The branch label just moves to whatever you commit next.
- "fatal: A branch named 'feature' already exists": you tried to create a branch that's already there. Use git switch feature to move to it instead of recreating it.
- Merging in the wrong direction: git merge pulls the named branch into the one you're on . Switch to main first, then git merge feature — not the other way around.
Pro Tips
- 💡 One branch per task: name it for the work — fix-navbar , add-search — so the branch list reads like a to-do list.
- 💡 Visualise often: git log --graph --oneline --all is your map. Alias it to something short like git lg .
- 💡 Delete merged branches: run git branch --merged now and then and clean up with -d so the list stays meaningful.
- 💡 Never rebase shared history: rebase only your own local, unpushed branches.
📋 Quick Reference
Command
Purpose
git branch
List branches (current marked *)
git branch name
Create a branch
git switch -c name
Create and switch (≡ checkout -b)
git switch name
Switch to an existing branch
git merge branch
Merge branch into the current one
git branch -d name
Safe-delete a merged branch
git branch -D name
Force-delete an unmerged branch
git log --graph --oneline --all
Draw the whole history as a graph
git stash / pop
Shelve / restore uncommitted work
Frequently Asked Questions
Mini-Challenge: Ship a Feature Branch
No commands given this time — just the plan and a blank canvas. Work through the whole branch lifecycle in your own terminal, then check your graph against the expected result in the comments.
🎉 Lesson Complete!
- ✅ A branch is a movable label pointing at a commit — branching copies no files
- ✅ git switch -c name (or git checkout -b name ) creates and switches in one step
- ✅ HEAD is "you are here" — it follows you as you switch branches
- ✅ git merge fast-forwards when possible, else makes a two-parent merge commit
- ✅ -d safe-deletes merged branches; -D force-deletes unmerged ones
- ✅ git log --graph --oneline --all draws your whole history
- ✅ Next lesson: push your branches to GitHub and learn remote repository workflows
Practice quiz
What is a Git branch?
- A full copy of every file in the project
- A movable label that points at a commit
- A remote server
- A saved snapshot of your files
Answer: A movable label that points at a commit. A branch is just a lightweight, movable pointer to a commit; creating one copies no files.
Which command creates AND switches to a new branch in one step?
- git branch -c name
- git checkout name
- git switch name
- git switch -c name
Answer: git switch -c name. git switch -c name (equivalent to git checkout -b name) creates the branch and moves you onto it.
What is HEAD in Git?
- The 'you are here' pointer to your current branch and commit
- The first commit in the repo
- The remote's main branch
- The staging area
Answer: The 'you are here' pointer to your current branch and commit. HEAD points at the branch you're on, which points at your latest commit; it moves as you switch branches.
When does Git do a fast-forward merge?
- Whenever you merge any branch
- Only when there is a conflict
- When the receiving branch had no new commits since the other split off
- When both branches changed the same line
Answer: When the receiving branch had no new commits since the other split off. If main hasn't moved since the branch split off, Git just slides the label forward with no merge commit.
Before running git merge feature, which branch should you be on?
- The feature branch
- The branch you want to RECEIVE the work (e.g. main)
- Any branch, it doesn't matter
- A brand-new empty branch
Answer: The branch you want to RECEIVE the work (e.g. main). git merge pulls the named branch INTO the one you're on, so switch to the receiving branch first.
What does the lower-case git branch -d do?
- Safely deletes a branch, refusing if it isn't fully merged
- Force-deletes any branch
- Creates a new branch
- Renames a branch
Answer: Safely deletes a branch, refusing if it isn't fully merged. -d is the safe delete; Git refuses to remove a branch that has unmerged commits, protecting your work.
When does git merge create a new merge commit with two parents?
- Always, on every merge
- Never
- When both branches gained commits since they diverged
- Only on the first commit
Answer: When both branches gained commits since they diverged. A three-way merge commit is made when both branches advanced, so Git can't simply fast-forward.
What is the golden rule of git rebase?
- Always rebase main
- Rebase shared branches often
- Rebase only after pushing
- Never rebase commits you've already pushed and shared
Answer: Never rebase commits you've already pushed and shared. Rebasing rewrites history, so rebasing shared commits breaks everyone else's copy; only rebase your local work.
What does git stash do?
- Shelves uncommitted changes and cleans the working directory
- Permanently deletes your changes
- Pushes changes to the remote
- Creates a new branch
Answer: Shelves uncommitted changes and cleans the working directory. git stash tucks away uncommitted changes so you can switch branches with a clean working tree.
Which command draws your whole history, all branches, as an ASCII graph?
- git status --branches
- git branch --all
- git log --graph --oneline --all
- git show --graph
Answer: git log --graph --oneline --all. git log --graph --oneline --all draws every branch and merge as a compact graph.
Continue this course
- Previous: Git Basics: Clone, Add, Commit
- Next: Working with Remote Repositories