In the previous tutorial, we learned to create a repository, stage files, and make commits. All our work happened on one branch — main.
But what if you want to add a new feature without breaking your working code? What if two people need to work on different things at the same time?
This is why branches exist. A branch is a separate line of development. You can make changes on a branch without affecting other branches. When you are done, you merge the changes back.
What Is a Branch?
Think of branches like copies of your project. You create a branch, make changes on it, and the original stays untouched.
main: A --- B --- C
\
feature: D --- E
In this diagram:
mainhas commits A, B, and Cfeaturewas created from C- Commits D and E only exist on the
featurebranch mainis not affected by D and E
In reality, Git does not copy files. It uses pointers to track which commit each branch points to. This makes branches very fast and lightweight.
Creating a Branch
There are several ways to create a branch.
Create Without Switching
git branch feature/login
This creates the branch but keeps you on your current branch.
Create and Switch (Modern Way)
git switch -c feature/login
Switched to a new branch 'feature/login'
The -c flag means “create.” This creates the branch and switches to it in one step.
Create and Switch (Older Way)
git checkout -b feature/login
This does the same thing as git switch -c. You will see git checkout in older tutorials and documentation. Both work fine.
Switching Between Branches
Modern Way
git switch main
Switched to branch 'main'
Older Way
git checkout main
Both commands do the same thing. git switch was added in Git 2.23 to make things clearer. Use whichever you prefer, but git switch is recommended for new projects.
Important: You must commit or stash your changes before switching branches. If you have uncommitted changes, Git might not let you switch.
Listing Branches
See all local branches:
git branch
feature/login
* main
The * marks the branch you are currently on.
See all branches, including remote ones:
git branch -a
feature/login
* main
remotes/origin/main
remotes/origin/feature/signup
Remote branches show up with the remotes/origin/ prefix. We will cover remote branches in Git Tutorial #4.
Working on a Branch
Let’s walk through a full example. We will create a branch, make some changes, and commit them.
# Start from main
git switch main
# Create a new branch for our feature
git switch -c feature/greeting
Switched to a new branch 'feature/greeting'
Now make some changes:
echo "Welcome to my project!" > welcome.txt
git add welcome.txt
git commit -m "Add welcome message"
Make another commit on this branch:
echo "This project is a demo." >> welcome.txt
git add welcome.txt
git commit -m "Add project description to welcome"
Now switch back to main:
git switch main
Check if welcome.txt exists:
ls welcome.txt
ls: cannot access 'welcome.txt': No such file or directory
The file does not exist on main. It only exists on feature/greeting. This is the power of branches — your work is isolated.
The main Branch
The main branch (sometimes called master in older repositories) is the default branch. It represents the stable version of your project.
A common rule: do not work directly on main. Always create a branch for your changes. This keeps main clean and working.
What to do:
main → feature/login → commit → merge back to main
What NOT to do:
main → commit directly on main
When you work on a team, this rule is even more important. Everyone creates branches for their features and merges them back through pull requests (covered in Git Tutorial #4).
Branch Naming
Use clear names for your branches. Many teams follow a naming convention:
# Features
git switch -c feature/user-login
git switch -c feature/search-bar
# Bug fixes
git switch -c fix/login-crash
git switch -c fix/missing-email
# Experiments
git switch -c experiment/new-layout
Keep names short and descriptive. Use hyphens between words. Avoid spaces — they cause problems in branch names.
Deleting Branches
After merging a branch, you usually delete it to keep things clean.
Safe Delete
git branch -d feature/greeting
Deleted branch feature/greeting (was b2c3d4e).
The -d flag is safe. It only deletes the branch if it has been merged. If the branch has unmerged changes, Git will warn you:
error: The branch 'feature/greeting' is not fully merged.
If you are sure you want to delete it, run 'git branch -D feature/greeting'.
Force Delete
git branch -D feature/experiment
The uppercase -D deletes the branch even if it has unmerged work. Use this carefully — you might lose commits.
Note: You cannot delete the branch you are currently on. Switch to a different branch first.
Renaming a Branch
git branch -m old-name new-name
To rename the branch you are currently on:
git branch -m new-name
Visualizing Branches
Git can show you a visual history of your branches:
git log --oneline --graph --all
* e5f6g7h (feature/greeting) Add project description to welcome
* d4e5f6g Add welcome message
| * c3d4e5f (HEAD -> main) Update hello.txt
|/
* b2c3d4e Add .gitignore
* a1b2c3d Add hello.txt
This is very helpful. It shows:
- Which commits belong to which branch
- Where branches split off
- Where
HEADis (your current position)
The --graph flag draws the branch lines. The --all flag shows all branches, not just the current one.
A Practical Example
Let’s put it all together with a real scenario. Alex is building a website and wants to add two features at the same time.
# Start on main
git switch main
# Create branch for the navigation feature
git switch -c feature/navigation
echo "<nav>Home | About | Contact</nav>" > nav.html
git add nav.html
git commit -m "Add navigation bar"
# Switch back to main
git switch main
# Create branch for the footer feature
git switch -c feature/footer
echo "<footer>Copyright 2026</footer>" > footer.html
git add footer.html
git commit -m "Add footer"
Now Alex has three branches:
git branch
feature/navigation
* feature/footer
main
Each branch has its own changes. main has neither the navigation nor the footer. This is how teams work — everyone works on their own branch.
git log --oneline --graph --all
* f6g7h8i (HEAD -> feature/footer) Add footer
| * e5f6g7h (feature/navigation) Add navigation bar
|/
* a1b2c3d (main) Add hello.txt
In the next tutorial, we will learn how to merge these branches back together.
Switching Branches with Uncommitted Changes
What happens if you have uncommitted changes and try to switch branches?
# Edit a file on feature/footer
echo "Updated footer" >> footer.html
# Try to switch to main
git switch main
error: Your local changes to the following files would be overwritten by checkout:
footer.html
Please commit your changes or stash them before you switch branches.
Aborting
Git stops you. It does not want to overwrite your work. You have three options:
- Commit your changes —
git add . && git commit -m "Save work" - Stash your changes —
git stash(saves them temporarily, we cover this in Git Tutorial #3) - Discard your changes —
git restore .(careful, this deletes your work)
Checking Which Branch Has Your Commits
Sometimes you need to know which branches contain a specific commit.
git branch --contains a1b2c3d
feature/greeting
main
This shows that commit a1b2c3d exists on both feature/greeting and main.
To see which branches you have not merged yet:
git branch --no-merged
feature/footer
feature/navigation
These branches have work that has not been merged into your current branch. This helps you track what is still in progress.
And to see branches that are already merged:
git branch --merged
* main
feature/greeting
These branches are safe to delete because their changes are already in your current branch.
How Git Branches Work Internally
You do not need to know this to use branches, but it helps you understand why branches are so fast in Git.
A branch is just a pointer to a commit. When you create a branch, Git creates a small file (41 bytes) with a commit hash inside. That is it. No files are copied.
main → points to commit C
feature/login → points to commit E
HEAD → points to the current branch (main)
HEAD is a special pointer that tells Git which branch you are on. When you run git switch feature/login, Git updates HEAD to point to feature/login.
When you make a new commit, the current branch pointer moves forward:
Before commit:
feature/login → E
After commit:
feature/login → F (new commit, parent is E)
This is why creating and switching branches is instant in Git. There is no copying involved.
Best Practices for Branches
Here are some guidelines that work well for most teams:
- Keep branches short-lived. A branch should exist for days, not months. Long-lived branches accumulate conflicts.
- One feature per branch. Do not mix unrelated changes. If you are adding a login page, do not also fix the footer on the same branch.
- Branch from the latest main. Always pull the latest
mainbefore creating a new branch. This reduces merge conflicts later. - Delete branches after merging. Clean up your branch list regularly. Old branches create confusion about what is active.
# Good workflow
git switch main
git pull # Get latest changes
git switch -c feature/search # Branch from up-to-date main
# ... work, commit, merge ...
git branch -d feature/search # Clean up
Common Mistakes
Working directly on main — Always create a branch for your changes. If you accidentally commit to
main, you can move the commit to a new branch withgit branch feature/my-workfollowed bygit reset HEAD~1onmain. We cover this in Git Tutorial #5.Forgetting which branch you are on — Always check with
git branchor look at your terminal prompt. Many terminal setups show the current branch name. Committing to the wrong branch is a common problem.Not deleting merged branches — Old branches pile up and make
git branchoutput messy. Delete branches after merging them. Usegit branch -dfor safe deletion — it will not delete unmerged branches.
What’s Next?
You know how to create branches and work on them separately. But how do you bring the work back together?
In the next tutorial, we will learn about merging and rebasing — two ways to combine branches.
Git Tutorial #3: Merging and Rebasing — Combining Work
For a quick reference of all Git commands, check the Git Commands Cheat Sheet.
This is part 2 of the DevTools Tutorial series.