Last updated on 23rd May 2026

How to create a Git branch

Creating a branch is one of the most common things you do in Git, and there are three commands that can do it — git switch, git checkout, and git branch. They were added at different times, work slightly differently, and produce subtly different results.

This tutorial walks through each command, the conventions that make branches easy to live with at scale, and how to handle branches that already exist on a remote.

The three commands at a glance

Command Creates branch? Switches to it? Notes
git switch -c <name> Modern (Git 2.23+). The recommended default.
git checkout -b <name> Older but still everywhere. Identical effect to switch -c.
git branch <name> Creates the branch but leaves you where you are. Useful when you want to create from somewhere without leaving your current spot.

If you only remember one of them, remember git switch -c. Git's own documentation now treats switch as the preferred command and reserves checkout for restoring files. They produce the same result here — the difference is intent.

git switch -c — the modern way

git switch -c feature/shopping-cart
Switched to a new branch 'feature/shopping-cart'

-c is short for --create. The new branch is based on your current HEAD, so whatever commits you have on the branch you were on are now the starting point of feature/shopping-cart.

To verify:

git status
On branch feature/shopping-cart
nothing to commit, working tree clean

You're now on the new branch, ready to commit.

git checkout -b — the older equivalent

git checkout -b feature/shopping-cart
Switched to a new branch 'feature/shopping-cart'

Output and effect are identical to git switch -c. The reason git switch exists at all is that git checkout has historically meant too many things — switch branches, restore files, detach HEAD — so Git split the file-restoration side off into git restore and the branch-switching side off into git switch.

git checkout -b is going to keep working for the foreseeable future, but new tutorials and IDE integrations are increasingly using switch.

git branch — create without switching

git branch feature/shopping-cart

This creates the branch but leaves you on the branch you were already on. No output means it worked. To switch later:

git switch feature/shopping-cart

The two-step approach is useful when you're inside a long-running operation (a rebase, a bisect) and you want to bookmark the current point as a branch without leaving the operation.

Creating from a specific starting point

By default, the new branch starts from your current HEAD. You can branch from anywhere by passing a starting point as the last argument.

From another branch:

git switch -c release/v2 main

From a specific commit:

git switch -c hotfix/login 4f1c2a8

From a tag:

git switch -c support/v1.4 v1.4.0

This is how you would, for example, start a hotfix branch from the exact commit that's running in production rather than from the tip of main (which may have moved on since the release).

Branch naming conventions

Git accepts almost any name (no spaces, no .., no colons, no ~, no ^), but the conventions that actually matter are organizational. A few prefixes pay off:

Prefix Use for
feature/ New functionality (feature/shopping-cart)
bugfix/ Bug fixes that aren't urgent (bugfix/login-typo)
hotfix/ Urgent production fixes (hotfix/payment-race)
release/ Release-stabilisation branches (release/v2.1)
chore/ Maintenance, dependencies, refactors (chore/upgrade-rails)

Why bother? Two reasons:

  1. Sorting. git branch -a lists branches alphabetically. With prefixes, all the features cluster together and you can scan a long list at a glance.
  2. Automation. Most deployment tools — including DeployHQ — can match branch patterns. A rule like "deploy every push to release/* to staging" only works if your branches are named consistently.

Use forward slashes between segments. Git treats the slash as a folder separator inside .git/refs/heads/, so feature/shopping-cart is genuinely organised in the file system, not just visually.

Note: Don't name a branch the same as an existing tag. Git allows it, but commands like git checkout v1.0 become ambiguous, and you'll spend an hour figuring out why nothing behaves as expected.

Working with remote branches

The branches you create locally exist only on your machine until you push them.

Push a new branch to the remote

git push -u origin feature/shopping-cart

-u (short for --set-upstream) tells Git to remember that your local branch tracks the remote one. After this, plain git push and git pull work without arguments because Git knows where to send and fetch from.

* [new branch]    feature/shopping-cart -> feature/shopping-cart
Branch feature/shopping-cart set up to track remote branch feature/shopping-cart from origin

Create a local branch that tracks an existing remote branch

A teammate has pushed a branch you want to work on. After fetching:

git fetch origin
git switch feature/shopping-cart

If a local branch by that name doesn't exist yet but a remote one does, Git creates the local branch automatically and sets up tracking — this is the most ergonomic way to "check out a remote branch".

For explicit control:

git switch -c feature/shopping-cart origin/feature/shopping-cart

Or, with the older command:

git checkout --track origin/feature/shopping-cart

Clone a single branch from a remote

If you want to grab only a specific branch when cloning a repository — useful for very large repos or for CI jobs — pass -b:

git clone -b release/v2 --single-branch git@github.com:example/site.git

--single-branch tells Git not to fetch every other branch's history, which can dramatically reduce clone time on large projects. See cloning an existing repository for the wider cloning options.

Listing, renaming, and recovering branches

A quick run-through of the operations that go hand in hand with creation.

List branches

git branch          # local branches only
git branch -r       # remote-tracking branches only
git branch -a       # both
git branch --merged # branches fully merged into HEAD (safe to delete)

The current branch is marked with a *.

Rename a branch

git branch -m old-name new-name

If you're on the branch you want to rename, you can omit old-name:

git branch -m new-name

Renaming is local. To propagate to the remote, you delete the old remote branch and push the renamed one:

git push origin --delete old-name
git push -u origin new-name

See the rename-a-branch FAQ for the edge cases.

Recover a "lost" branch

If you deleted a branch and want it back, the reflog usually has you covered. Find the last commit on the branch:

git reflog

Look for the commit you remember being at the tip of the branch, then re-create:

git branch recovered-branch <hash>

The branch is back, pointing at the commit it was at when you deleted it. Git's reflog keeps entries for about 90 days by default, so most accidents are recoverable.

Practical recipes

"I want to start a new feature without leaving main" — git switch -c feature/<name>. You're on the new branch and main is untouched on disk.

"I need to start a hotfix from the exact commit in production, not the tip of main" — git switch -c hotfix/<name> <production-commit-hash>. See also cherry-picking commits for moving the fix back to other branches once it's tested.

"My teammate pushed a branch and I want to work on it" — git fetch origin, then git switch <branch-name>. Git creates the local branch and sets up tracking automatically.

"I want to clone only one branch from a huge repo" — git clone -b <branch> --single-branch <url>.

"I created a branch with a typo in the name" — git branch -m <wrong-name> <right-name> while you're on a different branch, or just git branch -m <right-name> while you're on it.

"I want to bookmark the current commit as a branch without switching" — git branch <name>. Useful before a git reset or a git rebase to keep an escape hatch.

These all work the same way against GitHub, GitLab, and Bitbucket — branch creation is a local operation; git push -u origin <branch> is what propagates it to the remote.

Quick reference

Goal Command
Create and switch (modern) git switch -c <name>
Create and switch (older) git checkout -b <name>
Create without switching git branch <name>
Create from another branch git switch -c <new> <source-branch>
Create from a commit hash git switch -c <new> <hash>
Create from a tag git switch -c <new> <tag>
Push and set upstream git push -u origin <name>
Check out an existing remote branch git switch <name> (after git fetch)
Clone a single branch git clone -b <name> --single-branch <url>
List local branches git branch
List all branches (local + remote) git branch -a
Rename a branch git branch -m <old> <new>
Recover a deleted branch git branch <name> <hash> (from git reflog)

Next steps


A consistent branch-naming scheme pays off the moment you connect deployments to Git. DeployHQ can match branch patterns like release/* or main and deploy automatically every time you push — so a new feature/ branch can become a preview environment, and a merged release/ branch can ship to production without anyone touching a control panel. Start deploying free.