Branches
Table of Contents
- Why Branches?
- What a Branch Really Is
- Create a Branch and Switch to It
- Work on the Branch
- Switching Changes Your Files
- Merging: The Fast-Forward
- Merging: The Merge Commit
- Cleaning Up and Naming Branches
- Try It Yourself
1. Why Branches?
So far every commit has gone in a single line, on main. That's fine
for small changes, but imagine you start building a new page, get
halfway, and then need to fix an urgent typo on the live site. Your
half-finished page is mixed in with everything else.
A branch is a separate line of work. You create one, make your
commits there, and main stays exactly as it was. When the work is
finished and working, you merge it back into main. If the idea
fails, you delete the branch and main never knew.
In real teams the rule is usually: main always works. Every new
feature or fix happens on its own branch first.
2. What a Branch Really Is
Branches sound heavy, but they're one of the lightest things in Git.
Each commit stores a pointer to the commit before it (its parent), so commits form a chain:
3f2a1c9 ← c47a2e9 ← 8b1e4d0 ← 1c7e5a2
↑
main ← HEAD
A branch is just a label pointing at one commit. When you commit, the label moves forward to the new commit. And HEAD — "you are here" from chapter 4 — points at the branch you're currently on.
That's all. Creating a branch doesn't copy any files; it just writes a new label. It's instant, even in a huge project.
3. Create a Branch and Switch to It
List your branches:
git branch
* main
There's one, and the * shows you're on it. Now create a branch for a
new About page and switch to it in one step:
git switch -c add-about
Switched to a new branch 'add-about'
(-c means "create". To switch to a branch that already exists, leave
it out: git switch main.)
git branch
* add-about
main
Both labels point at the same commit for now:
3f2a1c9 ← c47a2e9 ← 8b1e4d0 ← 1c7e5a2
↑
main, add-about ← HEAD
You may also see
git checkout -b add-aboutin older tutorials. It does the same thing.git switchis the newer, clearer command.
4. Work on the Branch
Create about.html:
<!DOCTYPE html>
<html>
<head>
<title>About Dara</title>
</head>
<body>
<h1>About me</h1>
<p>I'm a student who likes building things.</p>
<p><a href="index.html">Back home</a></p>
</body>
</html>
And add a link to it in index.html, just above </body>:
<p><a href="about.html">About me</a></p>
Commit as usual:
git add .
git commit -m "Add about page"
Only the branch you're on moves forward. main stays behind:
3f2a1c9 ← c47a2e9 ← 8b1e4d0 ← 1c7e5a2 ← b3d5f82
↑ ↑
main add-about ← HEAD
5. Switching Changes Your Files
Now for the part that surprises people. Keep your file manager or VS Code's file list open where you can see it, and switch back:
git switch main
about.html disappears, and the link vanishes from index.html.
Don't panic — nothing is lost. Git changed the files in your working
directory to match the commit main points at, and the About page
didn't exist there yet. Switch back:
git switch add-about
…and it's back. One folder, many versions, and Git swaps between them in an instant.
If you have uncommitted changes that would be overwritten, Git
refuses to switch and tells you why. Commit them (or throw them away
with git restore) first. Always check git status before switching.
6. Merging: The Fast-Forward
The About page is finished. To bring it into main, switch to the
branch you want to merge into, then merge the other branch:
git switch main
git merge add-about
Updating 1c7e5a2..b3d5f82
Fast-forward
about.html | 11 +++++++++++
index.html | 1 +
2 files changed, 12 insertions(+)
create mode 100644 about.html
Fast-forward means main hadn't moved since the branch was
created, so Git didn't need to combine anything. It just slid the
main label forward to the same commit:
3f2a1c9 ← c47a2e9 ← 8b1e4d0 ← 1c7e5a2 ← b3d5f82
↑
main, add-about
(HEAD is on main, because that's the branch you switched to.)
7. Merging: The Merge Commit
Fast-forwards are the easy case. In real life, main often moves on
while you're working on a branch — a teammate merged something, or you
fixed a typo. Let's create that situation.
Start a branch for a contact page:
git switch -c add-contact
Create contact.html:
<!DOCTYPE html>
<html>
<head>
<title>Contact Dara</title>
</head>
<body>
<h1>Say hello</h1>
<p>Email me at dara@example.com</p>
<p><a href="index.html">Back home</a></p>
</body>
</html>
git add contact.html
git commit -m "Add contact page"
Now go back to main and make a different change there — edit the
sentence in about.html:
git switch main
<p>I'm a student in Phnom Penh who likes building websites.</p>
git add about.html
git commit -m "Update about page text"
The two branches have now gone in different directions:
┌── 7e1a0c6 "Update about page text" ← main
... ← b3d5f82 ──┤
└── 2f9d7b4 "Add contact page" ← add-contact
Merge as before:
git merge add-contact
This time Git can't just slide a label forward. It combines the two
lines of work and records the result as a new merge commit — a
commit with two parents. Your editor opens with the message
Merge branch 'add-contact'. That's a fine message: save and close.
See the shape of your history with:
git log --oneline --graph
* 5a8c3e1 (HEAD -> main) Merge branch 'add-contact'
|\
| * 2f9d7b4 (add-contact) Add contact page
* | 7e1a0c6 Update about page text
|/
* b3d5f82 (add-about) Add about page
* 1c7e5a2 Revert "Add favorite food"
...
Read the lines on the left as tracks: the two branches split after
b3d5f82 and join again at the merge commit. main now has both the
contact page and the new about text.
Git could combine these automatically because the two branches changed different parts of the project. When two branches change the same lines, Git can't decide on its own — that's a merge conflict, and it's the next chapter.
8. Cleaning Up and Naming Branches
Once a branch is merged, its label isn't needed any more. Delete it:
git branch -d add-about
git branch -d add-contact
This only deletes the label — the commits are safely part of main.
Git even refuses with -d if a branch has commits that aren't merged
anywhere, so you can't lose work by accident. (-D, capital, forces
it. Be sure before you use that.)
Good branch names describe the work, in lowercase with dashes:
add-contact-pagefix-broken-footer-linkupdate-profile-photo
Many teams add a prefix such as feature/add-contact-page or
fix/footer-link. Follow whatever your team does.
9. Try It Yourself
- Make a branch and watch it move. Create
add-about, commit the About page, and usegit log --onelineon both branches to see which commit each label points at. - Watch your files change. Switch between
mainandadd-aboutwith your file list open, and seeabout.htmlappear and disappear. - Fast-forward merge
add-aboutintomain. - Make a merge commit. Create
add-contact, commit there, then commit a different change onmain, and merge. Look atgit log --oneline --graph. - Try a throwaway experiment. Create a branch called
crazy-idea, delete half ofindex.html, and commit. Then switch back tomain(everything is fine there) and delete the experiment withgit branch -D crazy-idea. That's how cheap it is to try an idea.
Next, let's make two branches change the same line — on purpose.
Buy Me a Coffee
Found this tutorial helpful? Consider buying me a coffee to support more free content!