03 October 2026

Checkout Branch from Remote

Reza Khosravi
No items found.

Table of Contents

Checkout Branch from Remote

You're on a clean working tree, your usual local branches are visible, and a teammate says, “The feature branch is ready.” You run git branch, but the branch isn't there. Then git checkout feature-x fails because Git can't find a local branch by that name.

This situation is normal. The branch may exist on GitHub, GitLab, or another remote repository, but your local clone won't automatically create a local working branch for every branch someone pushes. To checkout a branch from remote, you need to identify the right remote, refresh your remote references, and create or switch to a local branch without disturbing your current work.

When the Branch Exists Only on the Remote

Your first instinct may be to run git checkout feature-x again. That won't help if Git hasn't learned about the branch, or if the branch belongs to a remote other than origin. A clean git status only tells you that your current local work is committed or saved. It doesn't prove that your local repository knows about the latest branches on a server.

Git separates local branches from remote-tracking branches. A local branch is the branch you work on directly. A remote-tracking branch is a local reference that records the state of a branch on a remote repository. Git stores these references under names such as origin/feature-x, following the remote/branch naming pattern described in the Git documentation on remote branches.

Why a branch can be visible online but not locally

Most clones use origin for the repository they were cloned from, but teams often add another remote called upstream, or a remote with a developer's name. A branch pushed to upstream won't appear under origin/*, and a branch pushed after your last network operation won't appear in your local remote-tracking references until you fetch.

That's why these commands can show different information:

  • git branch lists local branches only.
  • git branch -r lists remote-tracking branches already known to your clone.
  • git ls-remote --heads origin asks the remote server what branch heads currently exist, without relying on your stale local references.

Practical rule: A branch being present on a hosting site doesn't mean your local Git client has fetched its reference.

The safe mental model is simple. Listing tells you where the branch is, fetching updates your local knowledge, and checkout or switch creates the local workspace branch. Fetching doesn't replace the files in your working tree, so you can refresh references before deciding which branch to use.

The typical sequence is therefore:

  1. Find the exact branch name and remote.
  2. Fetch that branch.
  3. Create a local tracking branch or let Git create one when the name is unambiguous.

That sequence avoids guessing whether feature-x belongs to origin, upstream, or another remote.

The Core Fetch and Checkout Workflow

Start by checking the remote-tracking branches your clone already knows:

git branch -r

You might see:

origin/HEAD -> origin/mainorigin/mainorigin/feature-x

If origin/feature-x is listed, Git already has a local reference for the remote branch. If it isn't listed, query the remote directly:

git ls-remote --heads origin

This is useful when you need to confirm the exact spelling, including slashes and capitalization. Once you know the remote and branch, fetch it:

git fetch origin feature-x

git fetch downloads the remote reference and related objects without merging them into your current branch or changing the files in your working tree. If you need to refresh every configured remote instead, use:

git fetch --all

Create the local branch explicitly

The most predictable command is the explicit form:

git checkout -b feature-x origin/feature-x

This creates a local branch named feature-x, starts it from origin/feature-x, and configures the local branch to track that remote branch. The Atlassian Git checkout guide documents this historical pattern for creating a local branch from a remote branch.

On modern Git, a simpler command often works after fetching:

git checkout feature-x

Git can treat this as a request to create a local tracking branch when exactly one remote has a matching tracking branch. That convenience is useful in a simple repository, but it becomes less reliable when multiple remotes expose the same branch name.

The modern branch-focused equivalent is:

git switch feature-x

Or use the fully explicit form:

git switch -c feature-x --track origin/feature-x

The -c option creates the local branch, while --track records origin/feature-x as its upstream.

Verify what Git created

After switching, verify both the current branch and its upstream:

git branchgit branch -vvgit status

The asterisk in git branch identifies the current branch. git branch -vv shows the upstream reference and whether the local branch is ahead of or behind it. git status confirms that you're on the intended branch and displays tracking information when an upstream is configured.

CommandPurposeExpected result
git branch -rList known remote-tracking branchesShows references such as origin/feature-x
git ls-remote --heads originCheck branch heads directly on a remoteShows branch references currently advertised by origin
git fetch origin feature-xRefresh one remote branch referenceUpdates local knowledge without changing your working tree
git checkout -b feature-x origin/feature-xCreate an explicit local branchCreates feature-x from the selected remote branch
git switch -c feature-x --track origin/feature-xModern explicit branch creationCreates and configures a tracking branch
git branch -vvInspect upstream configurationShows the local branch and its tracked remote

If your Git installation predates git switch, use git checkout and its explicit -b and --track options. The important distinction isn't the command's age. It's whether you've selected the intended remote and created a local branch instead of merely viewing a remote-tracking reference.

How Tracking Branches Actually Work

A tracking branch is a local branch with an upstream configuration. Git stores the remote name and remote branch name in the repository configuration, commonly in .git/config. For example, a local feature-x branch may track origin/feature-x.

That relationship gives Git context for common commands. git status can report whether your local commits are ahead of or behind the upstream. git pull can fetch and integrate from the configured upstream without requiring a remote and branch name every time. git push can also use the configured destination instead of making you repeat it.

When Git guesses correctly

Git can automatically create a tracking branch when the requested branch name matches a uniquely available remote-tracking branch. For example, if only origin/feature-x exists, this may be enough after fetching:

git switch feature-x

The same principle applies to the checkout form:

git checkout feature-x

Git's remote-branch behavior has evolved from the older explicit pattern toward this simpler experience. The modern git switch documentation explains how Git can guess a remote branch and create a tracking branch when the name is unique, and how options such as --no-guess disable that behavior.

When Git refuses to guess

Suppose both of these references exist:

origin/feature-xupstream/feature-x

Now git switch feature-x doesn't contain enough information to choose safely. Git may refuse because the branch name is ambiguous. That refusal is helpful. Automatically tracking the wrong remote can send your future pulls and pushes in an unexpected direction.

Choose the remote explicitly:

git switch -c feature-x --track origin/feature-x

You can inspect the upstream of the branch you're currently using with:

git rev-parse --abbrev-ref @{u}

To point an existing local branch at a different upstream:

git branch --set-upstream-to=origin/feature-x feature-x

To remove the upstream relationship:

git branch --unset-upstream

A list of four essential habits for managing Git remote branches to keep workflows organized and error-free.

A remote-tracking branch is not a second working copy and it isn't a branch you should normally commit to directly. It's Git's local record of the remote branch's last fetched state. The local tracking branch is where you do your work, and the upstream relationship tells Git where that work should be compared or sent.

Checkout Versus Switch Versus Restore

git checkout is familiar because it handles several unrelated jobs. It can switch branches, create branches, check out a remote-tracking reference, restore files, and place HEAD in a detached state. That flexibility is powerful, but it also makes commands harder to read and mistakes easier to make.

For remote branch work, the command's intent matters. Compare the following:

git checkout feature-x

This may switch to an existing local branch or create a tracking branch when Git finds one unambiguous remote match.

git checkout -b feature-x origin/feature-x

This is explicit and works well when you need compatibility with older Git installations.

git switch -c feature-x --track origin/feature-x

This expresses the same operation with a branch-specific command. The local branch is created, its starting point is named, and its upstream is configured in one line.

Why switch is easier to reason about

git switch is dedicated to changing branches and managing branch creation. Its flags make the intent visible:

  • git switch feature-x changes to an existing branch or uses Git's remote-branch guessing when appropriate.
  • git switch -c feature-x creates a branch from the current commit.
  • git switch -c feature-x --track origin/feature-x creates a local branch from a selected remote branch.
  • git switch --detach origin/feature-x deliberately checks out the remote-tracking commit without creating a local branch.

That last command can be useful for inspection, but it isn't the normal way to begin feature work.

git restore handles file content, not branch movement. For example:

git restore README.md

This restores a file from the relevant commit context. It won't switch you to feature-x, create a tracking branch, or change the branch shown by git status.

CommandPrimary purposeUse for remote branches?Example
git checkoutLegacy branch switching and other checkout operationsYes, especially with explicit optionsgit checkout -b feature-x origin/feature-x
git switchBranch switching and branch creationYes, preferred for new workflowsgit switch -c feature-x --track origin/feature-x
git restoreRestore file contentNo, it isn't a branch commandgit restore README.md

Use git switch for new branch work when it's available. Use git checkout when you're supporting an older environment or maintaining an established command style. Don't use git restore to change branches.

Real Workflows With Multiple Remotes and Similar Names

Multiple remotes turn a convenient command into a potential ambiguity. A fork-based repository often has origin pointing to your fork and upstream pointing to the canonical project. Both remotes may expose a branch named main, yet those references can point to different commits.

A diagram illustrating a workflow of managing multiple remote work environments from a single local workspace.

Scenario one, choosing between origin and upstream

First inspect the configured remotes:

git remote -vgit branch -r

If both references exist, qualify the remote when you only need to inspect or temporarily visit its branch:

git checkout upstream/main

That checks out the remote-tracking reference directly, so HEAD will be detached. For regular work, create a local branch from the intended remote:

git switch -c upstream-main --track upstream/main

If the local branch is called main, make sure you aren't already using that name:

git switch -c main --track upstream/main

Verify the result:

git branch -vv

Scenario two, identical feature names on two remotes

Assume both remotes contain feature-x. Don't rely on git switch feature-x to infer your intent. Fetch and create the local branch with the remote named explicitly:

git fetch origin feature-xgit switch -c feature-x --track origin/feature-x

If you need the version from upstream instead:

git fetch upstream feature-xgit switch -c feature-x-upstream --track upstream/feature-x

Using distinct local names is often clearer when you need to compare both branches. You can also inspect each remote directly:

git ls-remote --heads origin feature-xgit ls-remote --heads upstream feature-x

The verification command is:

git status -sb

It should show the local branch and its selected upstream.

Scenario three, detached HEAD after direct checkout

This command is valid:

git checkout origin/main

It checks out the commit currently referenced by origin/main, but it doesn't create a local branch. Git reports a detached HEAD because new commits would not belong to a named local branch.

If you intend to work from that point, create a branch immediately:

git switch -c main origin/main

Or, using the older syntax:

git checkout -b main origin/main

If you only inspected the commit and want to return to an existing local branch:

git switch feature-x

Check the final state:

git branch -vvgit status -sb

Remote selection is also part of a secure delivery workflow. Teams that connect source control to automated builds and reviews can find related guidance on CI/CD pipeline security, especially when branch references determine what code enters a pipeline.

Fixing the Errors That Catch Everyone

Most remote checkout failures come from one of three causes: Git hasn't fetched the reference, the branch name is wrong, or the command left you on a remote-tracking reference instead of a local branch. The error text usually points toward the cause if you read it at face value.

Error messages and direct fixes

Error messageRoot causeFix
error: pathspec 'feature-x' did not match any file(s) known to gitThe branch hasn't been fetched, or the name is misspelledRun git fetch --all --prune, then confirm with git branch -r
fatal: 'origin/main' is not a commitA remote reference was passed to a command that expects a different object or syntaxCreate or switch to a local branch with git switch -c main origin/main
Detached HEAD warningYou checked out origin/main directlyCreate a local branch with git switch -c main origin/main
fatal: ambiguous refnameMultiple remotes or refs share the requested nameQualify the reference, such as origin/feature-x
Already up to date when you expected new workYour remote-tracking references may be staleFetch again before interpreting the result

For the pathspec error, begin with the exact name:

git branch -rgit fetch origin feature-xgit switch -c feature-x --track origin/feature-x

If the branch still doesn't appear, check the remote itself:

git ls-remote --heads origin

A typo in feature-x, a branch renamed by a teammate, or a branch hosted on upstream produces the same frustrating first symptom.

Don't confuse a successful pull with current remote knowledge

git pull operates using the current branch's configured upstream. If that upstream reference hasn't been refreshed, a result such as Already up to date only describes the information Git currently has. It doesn't establish that you fetched every remote or discovered a newly created branch.

Use this refresh before retrying:

git fetch --all --prunegit branch -r

The --prune option removes stale remote-tracking references for branches that no longer exist on the remote. It helps keep the branch list aligned with the server rather than preserving old names indefinitely.

If Git reports an ambiguous reference, qualify both the fetch and branch creation:

git fetch origin feature-xgit switch -c feature-x --track origin/feature-x

For repositories where automation depends on branch names and environment values, it's also useful to review GitHub Actions environment variables alongside the repository's branch and workflow configuration. A correct local checkout won't fix a pipeline that selects a different ref.

Habits That Keep Remote Branch Work Boring

Reliable remote branch work comes from small checks, not clever shortcuts. Before switching, run:

git remote -vgit branch -vv

That tells you which repositories exist locally and what your current branches track. Refresh references with pruning:

git fetch --all --prune

When you publish a new local branch, set its upstream deliberately:

git push -u origin feature-x

After switching, confirm both the working state and upstream:

git statusgit rev-parse --abbrev-ref --symbolic-full-name @{u}

A checklist infographic titled Habits That Keep Remote Branch Work Boring, listing common negative workplace behaviors.

Use explicit --track remote/name whenever a repository has multiple remotes or repeated branch names. For long-lived local branches that should never automatically follow origin, inspect and adjust the branch configuration directly with git config, including the branch's remote and upstream settings. Keep those decisions documented alongside your team's security policy application when branch selection affects controlled delivery paths.


DevArmor helps teams maintain continuous threat models, security design reviews, and Policy-as-Code enforcement across repositories, pull requests, and developer tools. If you want branch and code changes to carry clear security context through delivery, visit DevArmor to see how the platform fits into your workflow.

Table of Contents

Subscribe