Skip to content
DevOps devops git 5 min read

Branching & Merging

A branch in Git is a separate line of work. It lets you build a new feature or fix a bug without touching the main code that everyone relies on. When your work is ready, you bring it back into the main line with a merge (the act of combining two branches into one). Branching is the heart of how teams work with Git, and the good news is that it is fast, cheap, and safe to do.

Why branches are cheap in Git

In many older version control tools, a branch meant copying every file into a new folder, which was slow and used lots of disk space. Git does not work that way.

Under the hood, a branch in Git is just a tiny file that holds one thing: the ID of a commit (a saved snapshot of your project). That is roughly 40 characters of text. Creating a branch does not copy any of your files. It simply creates a new pointer to an existing snapshot.

Because branches are so light, the normal habit in Git is to make a new branch for almost everything: every feature, every bug fix, every experiment. You are encouraged to create them freely and delete them when you are done.

Tip: A branch name is just a label that moves forward as you add commits. Think of main as a sticky note stuck to the latest commit. When you commit, Git peels the note off and sticks it on the new commit.

Looking at your branches

To see the branches in your project, run git branch. The branch with a * next to it is the one you are currently on.

git branch

Output:

* main

A fresh project usually has only one branch. On modern Git (2.x and later, the default on Ubuntu 22.04 and 24.04) that branch is called main. Older projects may call it master.

Creating and switching branches

The modern command to move between branches is git switch. The older command git checkout still works and you will see it everywhere, but switch is clearer because it does only one job.

To create a new branch and move onto it at the same time, use the -c flag (short for “create”):

git switch -c feature-login

Output:

Switched to a new branch 'feature-login'

You are now on the feature-login branch. Any commits you make land here, not on main. Your main branch stays exactly as it was.

The table below shows the new and old commands side by side so you recognise both.

TaskModern command (Git 2.23+)Older command
Switch to an existing branchgit switch maingit checkout main
Create a branch and switch to itgit switch -c feature-xgit checkout -b feature-x
Create a branch only (stay put)git branch feature-xgit branch feature-x
Go back to your previous branchgit switch -git checkout -

When to use which: prefer git switch for everyday work on any recent Ubuntu install. Only reach for checkout when following an old tutorial or script that uses it.

A full feature-branch workflow

Here is the everyday flow a developer follows. Imagine you need to add a login page.

# 1. Start from an up-to-date main branch
git switch main
git pull origin main

# 2. Create a branch for your feature
git switch -c feature-login

# 3. Do your work, then stage and commit it
git add .
git commit -m "Add login form and validation"

# 4. Switch back to main and bring your work in
git switch main
git merge feature-login

# 5. Delete the branch once it is merged
git branch -d feature-login

Output (from the merge step):

Updating 3a1f9c2..b7d4e10
Fast-forward
 src/login.js | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

The -d in the last step deletes the branch safely. Git refuses to delete it if the work has not been merged yet, which protects you from losing commits. Use a capital -D to force-delete, but only when you are sure you do not need the work.

Fast-forward vs merge commits

When you merge, Git picks one of two strategies depending on the history. Understanding the difference helps you read your project’s history later.

A fast-forward merge happens when main has not changed since you branched off it. There is nothing to combine, so Git simply slides the main label forward to your branch’s latest commit. No new commit is created. That is the “Fast-forward” line you saw in the output above.

A merge commit (also called a three-way merge) happens when both branches have new commits. Git cannot just slide the label, because the two histories have moved apart. Instead it creates a brand-new commit that has two parents, joining the two lines of work together.

SituationWhat Git doesNew commit created?
main unchanged since you branchedFast-forward (moves the label)No
Both branches have new commitsMerge commit (joins both histories)Yes

You can force a merge commit even when a fast-forward is possible, which keeps a clear record that a branch existed:

git merge --no-ff feature-login

Output:

Merge made by the 'recursive' strategy.
 src/login.js | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

When to use --no-ff: on shared team projects where you want every feature to show up as a clear, named bubble in the history. When NOT to: on a tiny solo project where the extra merge commits just add noise.

Gotcha: If both branches changed the same lines of the same file, Git cannot decide which version wins. It stops and reports a merge conflict that you must fix by hand. See the conflicts page linked below for how to resolve them.

Best Practices

  • Branch for every unit of work — one feature or fix per branch. It keeps changes small and easy to review.
  • Pull the latest main before you create a new branch so you start from current code.
  • Give branches short, descriptive names like feature-login or fix-payment-bug, not test or temp.
  • Commit and merge often so branches do not drift far from main and cause big conflicts later.
  • Delete branches after merging with git branch -d to keep your branch list tidy.
  • Use git switch (not checkout) for new work; it is harder to misuse.
  • Avoid committing directly to main on team projects — do the work on a branch and merge it in.
Last updated June 15, 2026
Was this helpful?