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:

  • main has commits A, B, and C
  • feature was created from C
  • Commits D and E only exist on the feature branch
  • main is 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 HEAD is (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:

  1. Commit your changesgit add . && git commit -m "Save work"
  2. Stash your changesgit stash (saves them temporarily, we cover this in Git Tutorial #3)
  3. Discard your changesgit 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 main before 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

  1. 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 with git branch feature/my-work followed by git reset HEAD~1 on main. We cover this in Git Tutorial #5.

  2. Forgetting which branch you are on — Always check with git branch or look at your terminal prompt. Many terminal setups show the current branch name. Committing to the wrong branch is a common problem.

  3. Not deleting merged branches — Old branches pile up and make git branch output messy. Delete branches after merging them. Use git branch -d for 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.