Last modified: January 02, 2021

This article is written in: 🇺🇸

Git branching

Git branches help you keep different versions of your codebase separate and make collaboration smoother. Think of them like parallel timelines for your project. By creating a branch, you're effectively saying, “I want to try something new without messing up the main timeline.”

Below, we’ll walk through what branches are, how they work, why and when to create them, and how to manage them with some straightforward Git commands.

.----( feature_x )----.
    /                       \
---A------B------C------D----E---( main )
          \                 /
       '----( fix_bug )-----'

Above is a sketch showing a simplified idea: multiple branches coming off a main history and potentially rejoining it after some work.

What are branches?

A branch in Git is just a pointer to a specific commit. By default, Git starts with a main branch (often called master or main). Whenever you make a new commit, Git moves that branch pointer forward to track your latest changes.

When you create a new branch, you’re simply telling Git to mark a specific commit as a “starting point” for a separate line of development. Any commits you make in that branch won’t appear on the main branch until you decide to merge them back.

For instance, consider a history like this:

A <-- B <-- C <-- D  (master)

If you create a new branch at commit D, Git sets up a pointer for that branch:

A <-- B <-- C <-- D
                ^
                |------( new_branch )
                
(master also points to D)

From here, any commits you make on new_branch won’t affect master until a merge happens.

How do branches work technically?

Under the hood, Git uses commits that form a directed acyclic graph (DAG). Each commit knows its parent commit(s). When you branch, you’re just adding a new pointer to one of those commits.

If you make a commit on that new branch, Git records the parent commit as the one you branched from, forming a new path:

A <-- B <-- C <-- D (master)
                  \
                   E (new_branch)

Here, E is a new commit. It only exists on new_branch unless or until you merge it back into master.

When to create branches

A common question is: “When should I branch out?”. Here are some typical scenarios:

Bug fixes

When you spot a bug, it’s often a good idea to create a new branch to fix it. You can then test the fix thoroughly without breaking the main code. If you’re not sure how long a fix will take (or it might cause unexpected side effects), isolating your changes on a new branch is safer.

New features

If you’re adding a new feature, do the work on a feature branch. This helps keep the main branch stable. You can experiment freely and only merge when your feature is ready to share with everyone else.

Long-lived branches

Some teams maintain long-running branches for major releases or specific versions. The master (or main) branch is usually considered stable, while a dev branch might be used to integrate features from multiple short-lived branches before they’re merged to master.

Continuous integration

Teams often merge code into the main branch frequently—sometimes daily or even multiple times per day. The goal here is to keep the code in a “working” state and prevent large, unmerged branches from drifting too far behind. Smaller, more frequent merges reduce the risk of huge merge conflicts later.

(short_feature_branch)
        /
---A----B----C----D----E---(master)
                \
                 F----G----(another_feature_branch)

The shorter your branch’s lifespan, the smoother the merge back into the main line typically is.

Listing branches

To list all local branches, you can run:

git branch

Git will print something like:

branch1
* branch2
  branch3

The asterisk (*) shows the branch you’re currently on.

To list all branches (local and remote), use:

git branch -a

Output example:

branch1
* branch2
  branch3
  remotes/origin/branch1
  remotes/origin/branch2
  remotes/origin/branch3

Remote branches typically show up as remotes/origin/..., indicating branches that live on the remote repository.

Creating branches

To create a new branch, use:

git branch new_branch

This creates the branch new_branch but doesn’t switch you to it. If you immediately check git branch, you’ll see new_branch listed, but it won’t have the asterisk next to it. To switch to that branch, run:

git checkout new_branch

Alternatively, you can create and switch in one go:

git checkout -b new_branch

That command says, “Make a new branch called new_branch and check it out right away.”

Switching branches

Once a branch exists, you switch to it with:

git checkout branch1

Any commits you make now will belong to branch1. If you switch back to master (git checkout master), you’ll return to the previous state of the code in that branch.

Merging branches

When your work in a branch is ready to join another branch (often master), you’ll merge. First, switch to the branch you want to merge into:

git checkout branch2

Then run:

git merge branch1

This tells Git: “Take all the commits from branch1 and merge them into branch2.” If everything goes smoothly, Git will create a new “merge commit.” Sometimes you’ll encounter conflicts if both branches changed the same lines in different ways. If that happens, Git will pause the merge and let you resolve the conflicts manually in the affected files.

Here’s an example merge flow and its typical output:

$ git checkout master
Switched to branch 'master'

$ git merge new_branch
Updating d34f00d..a1b2c3
Fast-forward
 file1.txt | 2 +-
 file2.txt | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

In the output above, Git performed a fast-forward merge, which just moves the branch pointer forward because master was directly behind new_branch.

Deleting branches

Once you’ve merged a branch (or if you decide it’s no longer needed), you can delete it:

git branch -d branch1

Git will warn you if the branch hasn’t been merged. In that case, you can force-delete with:

git branch -D branch1

But beware: forcing a delete can throw away commits that aren’t merged anywhere else. Make sure you don’t lose important work.

Best practices

When working with branches, it's important to follow a few best practices to keep your repository organized and easy to work with:

Table of Contents

    Git branching
    1. What are branches?
    2. How do branches work technically?
    3. When to create branches
      1. Bug fixes
      2. New features
      3. Long-lived branches
      4. Continuous integration
    4. Listing branches
    5. Creating branches
    6. Switching branches
    7. Merging branches
    8. Deleting branches
    9. Best practices