Changing branches in Git is a small operation until the target branch lives only on a remote, your working tree has edits, or an old checkout example leaves you guessing which form is safe. To switch Git branches cleanly, use git switch for the branch move itself, verify the branch Git can see, and choose an explicit remote or stash path when Git cannot guess safely.
The commands work the same in Linux terminals, SSH sessions, and Git Bash because Git owns the branch operation, not the shell prompt. Package-manager commands appear only for systems where Git is missing or older than Git 2.23, the release series that added git switch.
Understand the Git Switch Command
To switch Git branches, use git switch <branch> for an existing local branch, git switch -c <new-branch> to create and switch in one step, git switch <branch> or git switch --track origin/<branch> for a remote-tracking branch, and git switch - to return to the previous branch.
Git’s git-switch manual page defines
git switchas the branch-switching command, while git-checkout remains the broader legacy command that also handles path checkout behavior. Usecheckoutonly when an older Git install or team workflow requires it.
Git Switch Branch Syntax
git switch is intentionally narrower than git checkout. It updates the working tree and index to another branch or detached commit state, but it does not double as the normal command for restoring file contents from the index. Use these forms as the core syntax.
git switch <existing-branch>
git switch -c <new-branch>
git switch -c <new-branch> <start-point>
git switch <remote-branch-name>
git switch --track origin/<remote-branch-name>
git switch -
git switch --detach <commit>
The git-branch manual page covers branch listing, upstream tracking, and branch rename behavior around these commands. In daily use, -c means “create the branch first,” --track means “create a local branch with upstream tracking,” and --detach means “inspect a commit without moving a branch pointer.”
Check the Current Git Branch First
Before changing branches, confirm where you are. git branch --show-current prints only the current branch name, while git status --short --branch also shows upstream tracking and local file changes.
git branch --show-current
git status --short --branch
main ## main...origin/main
If the status output includes modified files, decide what to do with those changes before switching to a branch that edits the same paths.
Git Switch vs Git Checkout Equivalents
Modern branch work should start with git switch. Keep the older git checkout equivalents nearby when you maintain old scripts, follow older project notes, or work on a system whose Git version predates 2.23.
| Branch Task | Modern Command | Legacy Equivalent |
|---|---|---|
| Switch to an existing branch | git switch feature/login-form | git checkout feature/login-form |
| Create and switch to a branch | git switch -c hotfix/session-timeout | git checkout -b hotfix/session-timeout |
| Create from a specific starting point | git switch -c docs/release-notes origin/main | git checkout -b docs/release-notes origin/main |
| Track a remote branch explicitly | git switch --track origin/feature/api-cleanup | git checkout --track origin/feature/api-cleanup |
| Inspect a commit without a branch | git switch --detach HEAD~1 | git checkout HEAD~1 |
| Restore file contents | git restore README.md | git checkout -- README.md |
The final row is the important boundary: file restoration is not a branch switch. Use git restore for file content recovery on modern Git instead of stretching git switch into a job it does not own.
Git Switch Branch Quick Reference
| Task | Command | What It Does |
|---|---|---|
| Show the current branch | git branch --show-current | Prints only the active branch name. |
| List local and remote branches | git branch -a | Shows local branches and remote-tracking branch names. |
| Switch to an existing local branch | git switch feature/release-notes | Moves your working tree to a branch that already exists locally. |
| Create and switch to a new branch | git switch -c hotfix/session-timeout | Creates the branch from the current HEAD and switches to it. |
| Create a branch from another start point | git switch -c docs/release-notes origin/main | Creates the branch from the named branch, tag, or commit. |
| Switch to a remote branch by name | git switch feature/api-cleanup | Creates a tracking branch when exactly one remote branch matches. |
| Switch to a remote branch explicitly | git switch --track origin/feature/api-cleanup | Creates the local branch from the named remote branch. |
| Use a different local branch name | git switch -c api-cleanup-review --track origin/feature/api-cleanup | Tracks the remote branch with a shorter or local-only name. |
| Jump back to the previous branch | git switch - | Returns to the branch or commit you were on before the current one. |
| Inspect an older commit | git switch --detach HEAD~1 | Detaches HEAD for temporary inspection. |
Install Git or Verify Git Switch Availability
Git is already present on many developer desktops and build images, but minimal servers, containers, and older systems may still need a package install or update. Install Git only if git --version fails or reports a release older than 2.23.
Check the Installed Git Version
Run the version check first when Git may already be installed:
git --version
The output should start with git version followed by the installed release. If the version is older than 2.23, update Git from your distro or use git checkout <branch> and git checkout -b <new-branch> until a newer Git build is available.
Install Git on Debian, Ubuntu, and Linux Mint
sudo apt update && sudo apt install git
Install Git on Fedora, RHEL, Rocky Linux, AlmaLinux, and CentOS Stream
sudo dnf install git
Install Git on Arch Linux
sudo pacman -S git
Install Git on openSUSE
sudo zypper install git
For package-source details beyond the quick commands, use the distro guides to Install Git on Ubuntu, Install Git on Debian, Install Git on Fedora, Install Git on Linux Mint, Install Git on Arch Linux, Install Git on Rocky Linux, or Install Git on CentOS Stream.
If a new Git setup can switch branches but cannot commit because the author identity is missing, configure Git username and email before creating real project commits.
Practice Local Git Switch Branch Examples
Most branch changes stay local. Start by listing the branches Git already knows, then switch to an existing branch or create the next one from the correct starting point.
List Local and Remote Git Branches Before Switching
git branch -a shows local branches first and remote-tracking branches underneath. The asterisk marks the branch currently checked out in the working tree.
git branch -a
feature/release-notes * main remotes/origin/HEAD -> origin/main remotes/origin/feature/api-cleanup remotes/origin/feature/login-form remotes/origin/main
Entries such as feature/release-notes are local branches. Entries prefixed with remotes/origin/ are remote-tracking references Git fetched from the remote, not editable local branches yet.
Switch to an Existing Local Git Branch
Pass the local branch name directly when the branch already exists in your repository. This is the simplest branch switch and the form most developers use during normal work.
git switch feature/release-notes
git status --short --branch
Switched to branch 'feature/release-notes' ## feature/release-notes
The status line confirms that the working tree now points at feature/release-notes. If an upstream branch is configured, the same status command also shows the remote tracking pair.
Create and Switch to a New Git Branch
Add -c when the branch does not exist yet. The new branch starts from the current HEAD, so switch to the correct base branch before creating a feature, hotfix, or review branch.
git switch -c hotfix/session-timeout
git status --short --branch
Switched to a new branch 'hotfix/session-timeout' ## hotfix/session-timeout
This is the modern equivalent of git checkout -b hotfix/session-timeout. It creates the branch and moves the working tree in one transaction.
Create a New Branch from a Specific Starting Point
When the new branch should start somewhere other than the current branch, pass the starting point after the new branch name. The starting point can be a branch, tag, commit hash, or remote-tracking branch.
git switch -c docs/release-notes origin/main
git status --short --branch
Switched to a new branch 'docs/release-notes' branch 'docs/release-notes' set up to track 'origin/main'. ## docs/release-notes...origin/main
Tracking origin/main may be useful for a short-lived documentation branch, but most feature branches should track their own remote branch after the first push. Check the status line before assuming the upstream pair is what you want.
Practice Remote Git Switch Branch Examples
Remote branch switching needs one extra decision: whether Git can infer one matching remote branch or whether you should name the remote explicitly. Fetch first when a teammate created the branch and it does not appear in your branch list.
Refresh Remote Branches Before Switching
git fetch --prune origin refreshes remote-tracking branch names for origin and removes stale remote-tracking refs that no longer exist on the server. It does not switch branches or merge files into your current branch.
git fetch --prune origin
git branch -r
origin/HEAD -> origin/main origin/feature/api-cleanup origin/feature/login-form origin/main
Use the remote branch name without the origin/ prefix only when Git can match that name in exactly one remote.
Switch to a Remote Git Branch by Name
If one remote-tracking branch matches the name you typed, git switch creates the local branch and configures upstream tracking automatically.
git switch feature/api-cleanup
git status --short --branch
Switched to a new branch 'feature/api-cleanup' branch 'feature/api-cleanup' set up to track 'origin/feature/api-cleanup'. ## feature/api-cleanup...origin/feature/api-cleanup
This short form is convenient in repositories with one remote. Repositories with both origin and upstream should usually use the explicit tracking form.
Switch to a Remote Git Branch with Explicit Tracking
Use --track when you want to name the remote branch directly. This avoids ambiguity when multiple remotes have the same branch name.
git switch --track origin/feature/api-cleanup
git status --short --branch
Switched to a new branch 'feature/api-cleanup' branch 'feature/api-cleanup' set up to track 'origin/feature/api-cleanup'. ## feature/api-cleanup...origin/feature/api-cleanup
The local branch name is derived from the remote branch name. In this example, origin/feature/api-cleanup becomes the local branch feature/api-cleanup.
Use a Different Local Name for a Remote Git Branch
Sometimes a remote branch name is too long for local review work, or you need two local branches that point at different experiments. Combine -c with --track to choose the local branch name while still tracking the remote branch.
git switch -c api-cleanup-review --track origin/feature/api-cleanup
git status --short --branch
Switched to a new branch 'api-cleanup-review' branch 'api-cleanup-review' set up to track 'origin/feature/api-cleanup'. ## api-cleanup-review...origin/feature/api-cleanup
The branch name before --track is local. The branch name after --track is the remote-tracking branch Git will use as the upstream.
Use Advanced Git Switch Branch Workflows
After the everyday switch commands are clear, a few smaller patterns handle review loops, dirty working trees, and temporary commit inspection without turning a branch move into a recovery task.
Switch Back to the Previous Git Branch
The lone dash is shorthand for the previous checkout target, equivalent to @{-1}. It is useful when you keep bouncing between a main branch and one feature branch during review or testing.
git switch -
git status --short --branch
Switched to branch 'main' Your branch is up to date with 'origin/main'. ## main...origin/main
If the previous target was a detached commit instead of a branch, git switch - can return there as well. Check git status --short --branch when you need to know whether you are on a named branch or detached HEAD.
Choose How to Handle Local Changes Before Switching
Git does not require a perfectly clean working tree for every branch switch. It aborts only when the target branch would overwrite local changes. Use the current file state to choose the safest action.
| Working Tree State | Safer Command | When to Use It |
|---|---|---|
| No local changes | git switch <branch> | Normal branch switch. |
| Changes should stay on current branch | git commit or git stash push -u | Preserve work before switching away. |
| Changes should move to target branch | git stash push -u, switch, then git stash pop | Carry unfinished work to another branch deliberately. |
| Changes can be merged during switch | git switch -m <branch> | Ask Git to perform a three-way merge of local edits and the target branch. |
| Changes should be discarded | git switch --discard-changes <branch> | Throw away conflicting local modifications before moving branches. |
git switch --discard-changesandgit switch -frestore the working tree and index to the target branch. Rungit status --short --branchfirst and use this path only when the local edits are disposable.
Inspect an Older Commit Without Moving a Git Branch
If you need to inspect a commit instead of a branch, detach HEAD intentionally. This lets you review or test an older snapshot without moving any branch pointer.
git switch --detach HEAD~1
git status --short --branch
HEAD is now at 9148752 Initial commit ## HEAD (no branch)
Your short commit hash will differ. When the inspection is done, switch back to a real branch such as main. If the detached state turns into real work, create a branch immediately with git switch -c review-old-state before committing.
Troubleshoot Common Git Switch Errors
Most git switch errors come from one of four states: Git cannot see the branch, the branch exists only as a remote-tracking ref, more than one remote has the same branch name, or local edits would be overwritten.
Git Says the Branch Reference Is Invalid
A misspelled branch name, stale remote list, or branch that does not exist can produce this error:
git switch feature/payments-ui
fatal: invalid reference: feature/payments-ui
First check what Git can see locally and remotely. If the remote branch list is stale, fetch again and retry the real branch name.
git fetch --prune origin
git branch -a
git switch feature/api-cleanup
git status --short --branch
feature/release-notes * main remotes/origin/HEAD -> origin/main remotes/origin/feature/api-cleanup remotes/origin/feature/login-form remotes/origin/main Switched to a new branch 'feature/api-cleanup' branch 'feature/api-cleanup' set up to track 'origin/feature/api-cleanup'. ## feature/api-cleanup...origin/feature/api-cleanup
If the branch still does not appear after a fetch, the name is wrong, the branch is on another remote, or it has not been pushed yet.
Git Says a Branch Is Expected but You Passed a Remote Branch
Passing the full remote-tracking ref directly asks git switch to move to a ref that is not a local branch:
git switch origin/feature/api-cleanup
fatal: a branch is expected, got remote branch 'origin/feature/api-cleanup' hint: If you want to detach HEAD at the commit, try again with the --detach option.
Create a local tracking branch instead, then verify the upstream relationship.
git switch --track origin/feature/api-cleanup
git status --short --branch
Switched to a new branch 'feature/api-cleanup' branch 'feature/api-cleanup' set up to track 'origin/feature/api-cleanup'. ## feature/api-cleanup...origin/feature/api-cleanup
If you only want to inspect the remote branch without creating a local branch, use git switch --detach origin/feature/api-cleanup and return to a named branch before doing normal work.
Git Finds the Same Branch Name on Multiple Remotes
Repositories with both origin and upstream can expose the same branch name from more than one remote. In that case, the short form is ambiguous.
git switch feature/api-cleanup
hint: If you meant to check out a remote tracking branch on, e.g. 'origin', hint: you can do so by fully qualifying the name with the --track option: hint: hint: git switch --track origin/<name> hint: hint: If you'd like to always have checkouts of an ambiguous <name> prefer hint: one remote, e.g. the 'origin' remote, consider setting hint: checkout.defaultRemote=origin in your config. fatal: 'feature/api-cleanup' matched multiple (2) remote tracking branches
The safest fix is to name the remote branch explicitly:
git switch --track origin/feature/api-cleanup
git status --short --branch
Switched to a new branch 'feature/api-cleanup' branch 'feature/api-cleanup' set up to track 'origin/feature/api-cleanup'. ## feature/api-cleanup...origin/feature/api-cleanup
If your repository should always prefer one remote for guessed branch switches, set checkout.defaultRemote in that repository:
git config checkout.defaultRemote origin
Use repository-local config unless your personal workflow needs the same default across many repositories. A global default can hide remote-name mistakes in repositories that use a different branch ownership model.
Git Refuses to Switch Because Local Changes Would Be Overwritten
A branch switch that would overwrite your local file edits fails before Git changes branches:
git switch feature/login-form
error: Your local changes to the following files would be overwritten by checkout: login.txt Please commit your changes or stash them before you switch branches. Aborting
Check the working tree, stash the work when you need to keep it, switch branches, and confirm that the stash is available.
git status --short --branch
git stash push -u -m "login-switch-work"
git switch feature/login-form
git stash list
## main...origin/main [ahead 1]
M login.txt
Saved working directory and index state On main: login-switch-work
Switched to a new branch 'feature/login-form'
branch 'feature/login-form' set up to track 'origin/feature/login-form'.
stash@{0}: On main: login-switch-work
Run git stash pop only on the branch that should receive the saved work. If the stash applies with conflicts, resolve them like normal merge conflicts before continuing.
If the mistake is already committed on the wrong branch, handle the commit separately instead of trying to solve it with a branch switch. Use the workflow to undo the last Git commit before moving or reapplying the work.
Git Expects a Branch but You Passed a Commit
Passing a commit reference without detached mode produces this error:
git switch HEAD~1
fatal: a branch is expected, got commit 'HEAD~1' hint: If you want to detach HEAD at the commit, try again with the --detach option.
Use detached mode when the target is a commit hash, tag, or relative reference such as HEAD~1.
git switch --detach HEAD~1
git status --short --branch
HEAD is now at 9148752 Initial commit ## HEAD (no branch)
Create a branch before committing if the detached state becomes real work. Otherwise, switch back to the branch that should keep receiving commits.
Git Switch Branch Conclusion
Git branch switching is predictable once you separate local branches, remote-tracking refs, dirty working trees, and detached commits. Use git switch for modern branch movement, keep checkout for older compatibility, and verify tracking before you continue. When branch names need cleanup later, rename a local and remote Git branch before pushing more work.


Formatting tips for your comment
You can use basic HTML to format your comment. Useful tags currently allowed in published comments:
<code>command</code>command<strong>bold</strong><em>italic</em><a href="https://example.com">link</a><blockquote>quote</blockquote>