Chapter 12: Git Branch
Git Branch — the single most powerful and most-used feature after committing.
If commits are “save points,” branches are parallel universes where you can experiment safely without breaking the main story. Almost every real-world Git workflow (GitHub Flow, GitFlow, trunk-based, feature branches) revolves around them.
I’m going to explain it like we’re building a small todo app together — step by step, with real commands, outputs, analogies, and why branches exist.
1. What is a Git Branch? (Super simple analogy)
Imagine your project is a storybook:
- The main branch (or main in 2026) = the official published book everyone reads. Stable, production-ready.
- A branch = you make a photocopy of the current book, go to a quiet room, scribble wild ideas (new chapters, rewrite ending), while the original book stays untouched.
- Finished & good? → Merge your copy back into the main book.
- Bad idea? → Throw your copy away — main book unaffected.
Technically:
- A branch is just a lightweight movable pointer to a specific commit.
- When you create a branch, Git doesn’t copy files — it just says “from this commit onward, call this timeline ‘feature/dark-mode'”.
- HEAD (your current position) points to the tip of your current branch.
- Every new commit on a branch moves that branch pointer forward (main stays put until you merge).
2. Why Branches? (Real 2026 reasons)
- Work on new features / bug fixes without breaking production
- Multiple people / tasks at once (you on login, teammate on payment)
- Experiment safely (try risky refactor, throw away if fails)
- Isolate changes → easier code review via Pull Requests
- Maintain old versions (hotfix on v1.2 while main is v2.0)
- GitHub / GitLab / Bitbucket all build Pull Requests, Actions, Reviews around branches
In 2026, default branch is almost always main (Git has shifted fully from master since ~2020–2023; new repos use main out of the box).
3. Hands-on: Let’s Create & Use Branches Right Now
Start fresh or continue previous demo:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
mkdir todo-app-branches cd todo-app-branches git init # First commit on main echo "# Todo App 2026" > README.md git add README.md git commit -m "Initial commit: basic README" |
Check branches:
|
0 1 2 3 4 5 6 |
git branch |
Output:
|
0 1 2 3 4 5 6 |
* main |
→ * shows current branch (HEAD is here)
Create a new branch (two common ways):
Way A – Create without switching:
|
0 1 2 3 4 5 6 |
git branch feature/add-tasks |
Way B – Create and switch (most people prefer this – one-liner):
|
0 1 2 3 4 5 6 7 8 |
git checkout -b feature/add-tasks # or modern Git (2.23+): git switch -c feature/add-tasks |
Now:
|
0 1 2 3 4 5 6 |
git branch |
|
0 1 2 3 4 5 6 7 |
feature/add-tasks * main ← you were on main, now switched! |
No — after checkout -b or switch -c:
|
0 1 2 3 4 5 6 7 |
* feature/add-tasks main |
You’re now on the new branch — safe to experiment.
Make changes:
|
0 1 2 3 4 5 6 7 8 9 |
echo "- Buy milk" >> README.md echo "- Walk dog" >> README.md git add README.md git commit -m "Add initial todo items" |
Now history diverges:
|
0 1 2 3 4 5 6 7 |
git lg # assuming you have the alias from earlier # or git log --oneline --graph --decorate --all |
Something like:
|
0 1 2 3 4 5 6 7 |
* abc1234 (HEAD -> feature/add-tasks) Add initial todo items * def5678 (main) Initial commit: basic README |
→ main pointer stayed at old commit → feature/add-tasks moved forward
4. Switch Between Branches
|
0 1 2 3 4 5 6 7 |
git checkout main # or git switch main ← modern & safer |
→ Your files change back! README.md loses the new todos (because they live only on the other branch)
|
0 1 2 3 4 5 6 |
cat README.md # only original title |
Switch back:
|
0 1 2 3 4 5 6 7 |
git checkout feature/add-tasks # files with todos return! |
5. Merge Branch Back to Main (The Happy Ending)
When feature is ready:
|
0 1 2 3 4 5 6 7 |
git checkout main git merge feature/add-tasks |
Output (fast-forward merge – clean):
|
0 1 2 3 4 5 6 7 8 9 |
Updating def5678..abc1234 Fast-forward README.md | 2 ++ 1 file changed, 2 insertions(+) |
Now:
|
0 1 2 3 4 5 6 |
git lg |
|
0 1 2 3 4 5 6 7 |
* abc1234 (HEAD -> main, feature/add-tasks) Add initial todo items * def5678 Initial commit: basic README |
→ Both pointers now at same commit (merged)
Clean up (optional but good):
|
0 1 2 3 4 5 6 |
git branch -d feature/add-tasks # safe delete if merged |
6. Branch Commands Cheat Sheet (Daily 2026 Use)
| Action | Command (preferred) | Old / Alternative | Notes |
|---|---|---|---|
| List local branches | git branch | — | * = current |
| List all (local + remote) | git branch -a | — | -r for remote only |
| Create branch (no switch) | git branch feature/new-ui | — | Rarely used alone |
| Create + switch | git switch -c feature/new-ui | git checkout -b feature/new-ui | Modern Git recommends switch |
| Switch branch | git switch main | git checkout main | switch safer (won’t mess with files) |
| Merge into current branch | git merge feature/new-ui | — | Run from target branch (usually main) |
| Delete branch (safe) | git branch -d feature/old | — | Fails if not merged |
| Force delete | git branch -D feature/bad-experiment | — | Use when you don’t care |
| Rename current branch | git branch -m feature/better-name | — | Careful if pushed already |
| See last commit on each branch | git branch -v | — | Shows hash + message |
7. Quick Real-World Flow (What Most Teams Do in 2026)
- git checkout main && git pull → fresh main
- git switch -c feature/user-profile
- Work → add → commit (many times)
- git push -u origin feature/user-profile → share
- Create Pull Request on GitHub → review → merge
- git checkout main && git pull → update local main
- git branch -d feature/user-profile → cleanup
Got the branch feeling? Branches = cheap, fast, safe parallel timelines.
Next?
- Merge conflicts hands-on?
- Pull Requests with branches?
- Rebase vs merge?
- Remote branches & tracking?
Just say — we’ll continue the class. You’re doing awesome! 🚀
