GitSwitching Branches (git switch)

Switching Branches (git switch)

Switching branches is how you move between parallel lines of work. Under the hood, Git updates two things: the HEAD pointer (so future commits land on the new branch) and the files in your working directory (so what you see matches the new branch). For modern Git (2.23+), the preferred command is git switch.

The basic switch

Bash
git switch main
# Switched to branch 'main'

git switch feature-x
# Switched to branch 'feature-x'

Git updates your working directory to match the target branch. Files that exist on one branch but not the other are added or removed; modified files are rewritten. Anything you had not committed stays in your working directory and tries to merge with the new branch’s content.

What if I have uncommitted changes?
  • Clean working tree — switch happens instantly.

  • Uncommitted changes that don’t conflict with the target branch — Git carries them over to the new branch.

  • Uncommitted changes that DO conflict — Git refuses to switch and asks you to commit, stash, or discard.

When Git refuses to switch

Bash
git switch main
# error: Your local changes to the following files would be overwritten by checkout:
#   src/app.js
# Please commit your changes or stash them before you switch branches.

Three ways to proceed

Bash
# Option A: commit the changes
git add . && git commit -m "WIP"

# Option B: stash them — switch — restore them later
git stash
git switch main
# ... do whatever ...
git switch feature-x
git stash pop

# Option C: discard them
git restore .
git switch main
Create and switch in one step

-c (create)

Bash
git switch -c new-feature
# Creates 'new-feature' from current HEAD, switches to it
Switch to a remote branch

Auto-create a tracking branch

Bash
git fetch origin
git switch feature-x
# Git sees origin/feature-x and creates a local 'feature-x' that tracks it
Force a switch and lose changes

--discard-changes — DESTRUCTIVE

Bash
git switch --discard-changes main
# Discards all uncommitted edits and switches
Warning
`--discard-changes` permanently deletes your local modifications. Use it only when you are 100% sure.
Detached HEAD — switching to a commit, not a branch

Bash
git switch --detach 1f9ab2c
# You are in 'detached HEAD' state.
# Any commits you make here are not on any branch — they could be lost.

See the “Detached HEAD State” page for the full story. Briefly: it is fine for read-only investigation; if you start making commits, create a branch first.

Switch back to the previous branch

The dash shortcut

Bash
git switch -
# Switches back to the previously checked-out branch
# Same idea as 'cd -' in a shell
Inspecting the result

Bash
git status
# On branch main
# Your branch is up to date with 'origin/main'.

git branch --show-current
# main

# All branches with the current one marked
git branch
# * main
#   feature-x
#   bugfix-42
git switch vs git checkout
  • git checkout is older and overloaded — it can switch branches, restore files, AND detach HEAD. That overloading was a common source of beginner confusion.

  • git switch was added in Git 2.23 (2019) to do only one thing: change branches.

  • git restore was added at the same time to handle the “restore files” use case.

  • Modern documentation and IDEs prefer git switch / git restore over git checkout. Both still work.

Common errors
  • "would be overwritten by checkout" — uncommitted changes conflict. Commit, stash, or discard them first.

  • "pathspec did not match any known branch" — the branch name does not exist. Run git branch -a to see all known branches; git fetch if you expect a remote branch.

  • "reference is not a tree" — you used a commit hash but Git cannot find it. Maybe a typo or a deleted branch — try git reflog.

What about submodules?
Switching branches in a repo with submodules does NOT update the submodule contents by default. After the switch, run `git submodule update --init --recursive` to sync them.
Tip
Add an alias: git config --global alias.s switch. Now git s main, git s -c new-branch, and git s - become the standard rhythm of moving between work streams.