Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild

Create a Git Branch From the Current One: switch, checkout, and Getting the Base Right

Sean

Platform Writer

Aug 26, 2026
7 min read

git switch -c new-feature creates a branch from your current position and moves you onto it. git checkout -b new-feature does the same thing and is the older spelling. The command is not where people go wrong — the base commit is, and you rarely notice until the pull request shows forty files you did not touch.

Create a Git Branch From the Current One: switch, checkout, and Getting the Base Right

Branching in Git is cheap because a branch is just a pointer to a commit. Creating one takes no time and copies nothing.

What costs time is creating it from the wrong place: branching off a stale main, or off another feature branch by accident, and finding out at review time when your diff contains someone else’s work.

Table of contents

The commands

git switch -c new-feature              # from the current HEAD
git switch -c new-feature main         # explicitly from main
git switch -c new-feature origin/main  # from the remote's main
git switch -c hotfix v1.2.0            # from a tag
git switch -c investigate a1b2c3d      # from a specific commit

git switch and git restore were introduced in Git 2.23 to split up git checkout, which did too many unrelated things — changing branches, restoring files, and creating branches were all the same command, and the flags interacted confusingly.

The equivalences, since you will see both in every tutorial:

  • git switch -c name = git checkout -b name
  • git switch name = git checkout name
  • git switch - = git checkout - (back to the previous branch)

checkout is not deprecated and will keep working. switch is clearer about intent, and worth adopting for that reason alone.

To create a branch without moving onto it:

git branch new-feature main

Getting the base right

This is the actual skill. Before branching, know two things: where you are, and whether that is current.

git status                    # which branch am I on?
git log --oneline -3          # what is the last commit here?
git fetch origin              # update knowledge of the remote
git log --oneline -3 origin/main   # what does the remote main look like?

The reliable pattern for starting a feature, which sidesteps the whole problem:

git fetch origin
git switch -c new-feature origin/main

That branches from the remote’s current main regardless of what your local main looks like or which branch you happen to be standing on. It removes two mistakes at once — the stale local main, and branching off whatever you were last working on.

Check what you have actually based on afterwards:

git log --oneline origin/main..HEAD
# empty = your branch is exactly at origin/main
# commits listed = these are on your branch and not on main

If that shows commits you did not write, you branched off someone else’s work. Better to find out now than in review.

Fixing a branch created from the wrong base

Entirely recoverable, and the tool is rebase --onto, which is worth knowing precisely because this situation is common.

Say you branched from feature-a when you meant to branch from main, and have made three commits:

git rebase --onto main feature-a new-feature

Read that as: take the commits on new-feature that are not on feature-a, and replay them onto main. Your three commits move across; feature-a’s commits are left behind.

If you have not committed anything yet, it is simpler — just move the branch pointer:

git switch -c new-feature       # oops, wrong base, nothing committed
git reset --hard origin/main    # move it to the right base

And if you have already started work on the wrong branch entirely, without creating a new one, your commits can be moved:

git switch -c new-feature       # brings the uncommitted work along
# or if already committed on main:
git switch -c new-feature        # branch here, keeping the commits
git switch main
git reset --hard origin/main     # clean main back up

Create the branch first, then clean up the branch you should not have committed to. Doing it in the other order is how the commits get lost.

Tracking and pushing

A new local branch has no remote counterpart until you push it:

git push -u origin new-feature

-u sets the upstream, so subsequent git push and git pull need no arguments. Without it you get told off every time.

To make that automatic, since it is what you want every time:

git config --global push.autoSetupRemote true

Available since Git 2.37 and one of the better quality-of-life settings.

Two related conveniences worth having:

git branch -vv                  # branches with their upstreams and ahead/behind counts
git switch -                    # jump back to the previous branch

git switch - is the branch equivalent of cd -, and it is used constantly once you know it exists.

For checking out a branch that exists on the remote but not locally, recent Git does the right thing automatically:

git fetch origin
git switch someone-elses-branch    # creates a local branch tracking origin's

Naming and hygiene

A convention that survives contact with a real team:

feature/user-authentication
fix/login-redirect-loop
chore/upgrade-node-22
hotfix/payment-timeout

Prefixes group branches in listings and make the intent obvious in a pull request title. Include a ticket number if your team uses one — fix/PROJ-482-login-redirect is greppable a year later, which a branch called fix is not.

Practical constraints worth knowing:

  • No spaces. Use hyphens.
  • Avoid .., ~, ^, : and ? — Git rejects them because they mean things in revision syntax.
  • Case sensitivity varies by filesystem. Feature/Login and feature/login can collide on macOS and Windows.
  • You cannot have both a branch feature and a branch feature/login — the first blocks the second.

Delete branches once merged, locally and remotely:

git branch -d new-feature              # refuses if not merged
git push origin --delete new-feature
git fetch --prune                      # clear out remote-tracking refs that no longer exist

git fetch --prune is the one people skip, which is why git branch -a eventually lists dozens of branches that were deleted on the server months ago.

How this fits the rest of the stack

Branching well is mostly about knowing what your work is based on, because that base determines what your diff contains and what your deploy will actually run. A branch cut from a stale main produces a pull request that is harder to review and a merge that is more likely to conflict.

The same question applies at deploy time: which commit is running right now, and what changed since the last one. RunxBuild builds from a connected GitHub repository and keeps a build log and a rollback target per deploy, so the running version always maps back to a specific commit rather than to whatever was on the server. If you want to see what that service costs alongside a managed database and storage, the RunxBuild hosting calculator lists them separately.

Useful related references:

FAQ

What is the difference between git switch -c and git checkout -b?

Nothing functionally — both create a branch and move onto it. git switch was introduced in Git 2.23 to separate branch operations from file restoration, which checkout had confusingly combined. checkout still works and is not deprecated.

How do I create a branch from main without switching to main first?

git switch -c new-feature main branches from your local main. Better still, git fetch origin && git switch -c new-feature origin/main branches from the remote’s current main, which avoids the stale-local-main problem entirely.

I branched from the wrong branch. How do I fix it?

Use git rebase --onto main wrong-base your-branch, which replays your commits onto the correct base and leaves the wrong branch’s commits behind. If you have not committed anything yet, git reset --hard origin/main is enough.

How do I check what my branch is based on?

git log --oneline origin/main..HEAD lists commits on your branch that are not on main. If that output contains commits you did not write, you branched off someone else’s work rather than off main.

Why does git push complain about no upstream branch?

A new local branch has no remote counterpart until you push it with -u, as in git push -u origin new-feature. To make this automatic for every new branch, set git config --global push.autoSetupRemote true.

#git create a new branch from current#git#git branch#git switch#version control