Checking out a remote Git branch creates a local branch on your developer workstation that tracks a corresponding branch on the remote server (origin). Understanding the difference between remote tracking references (origin/feature), local branches (feature), and HEAD prevents accidental lost commits and detached HEAD states.
Remote Server (GitHub / GitLab):
└── origin/feature/payments ──(git fetch origin)──► Local Repo (.git/refs/remotes/origin/...)
│
▼ (git switch feature/payments)
Local Working Tree:
└── feature/payments [tracks origin]
New to this → start with The standard 2-step workflow. Detached HEAD recovery → Fixing detached HEAD. Merge vs Rebase → Git merge vs rebase guide. Interview prep → If an interviewer asks.
Real-world analogy
Imagine a central company whiteboard (GitHub). A colleague writes down a new project plan under origin/feature-auth.
- If you never look at the whiteboard (
git fetch), your notebook won't know the project exists. - If you read the whiteboard and transcribe it directly into your personal notebook (
git switch feature-auth), you have a local working copy you can safely edit and annotate. - If you try to write directly on the glass over your colleague's shoulder (
git checkout origin/feature-auth), you enter a "Detached HEAD" state: the moment someone walks past and wipes the glass, your unstored notes are gone.
The standard 2-step workflow
Modern Git (version 2.23+) split the overloaded git checkout command into git switch (for branches) and git restore (for files).
Step 1: Fetch remote refs from origin
git fetch origin
This synchronizes your local repository's knowledge of all remote branches, tags, and commits without touching your current working directory or modifying your uncommitted local files.
Step 2: Switch to the branch
# Modern syntax (Recommended):
git switch feature/invoices
# If you are using legacy Git (<2.23):
git checkout feature/invoices
If feature/invoices exists in exactly one remote (origin/feature/invoices) and does not exist locally yet, Git automatically:
- Creates a local branch named
feature/invoices. - Points it to the same commit as
origin/feature/invoices. - Sets up upstream tracking so
git pullandgit pushwork automatically.
Checking out with a custom local name or explicit upstream
If you want your local branch to have a different name than the remote branch:
# Creates local branch 'my-invoices' tracking 'origin/feature/invoices'
git switch -c my-invoices --track origin/feature/invoices
# Verify upstream tracking link
git status -sb
# Output: ## my-invoices...origin/feature/invoices
If a local branch already exists but lost its upstream tracking link:
git branch -u origin/feature/invoices
Recovering from a "Detached HEAD" state
If you accidentally run:
git checkout origin/feature/invoices # ❌ Enters Detached HEAD state
Git will warn: You are in 'detached HEAD' state. You can look around, make experimental changes...
If you made commits in Detached HEAD and want to save them:
Do not switch back to main yet! Run:
# 1. Create a new branch pointing to your current detached commit
git switch -c feature/saved-work
# 2. Push to origin
git push -u origin feature/saved-work
If you already switched away and lost your commits:
Retrieve the commit hash using the Git reference log (git reflog):
git reflog
# Look for the commit: "e4a19b2 HEAD@{1}: commit: Added invoice calculations"
# Restore into a new branch:
git switch -c feature/recovered-work e4a19b2
Pruning deleted remote branches
When pull requests are merged and deleted on GitHub, your local machine still keeps stale origin/feature references. Clean them with:
git fetch --prune origin
To configure Git to prune deleted branches automatically on every fetch:
git config --global fetch.prune true
Common mistakes and pitfalls
- Running
git checkout featurewithout fetching first: If a teammate pushed a new branch 5 minutes ago, local Git will returnerror: pathspec 'feature' did not match any file(s) known to git. Always rungit fetch originfirst. - Committing directly in Detached HEAD: Making commits while detached and then running
git checkout mainleaves those commits dangling without a branch reference, subjecting them to eventual Git garbage collection (git gc). - Name collision between branch name and file path: In legacy
git checkout, if a folder is namedapiand a branch is namedapi, runninggit checkout apican restore files instead of switching branches.git switch apiavoids this ambiguity completely.
If an interviewer asks
30-second answer: To check out a remote branch, run git fetch origin to update local tracking references, followed by git switch <branch-name>. Modern Git automatically creates the local branch and configures upstream tracking. Never commit directly to origin/<branch> as it enters a detached HEAD state.
Strong answer: In modern team workflows, we use git switch to separate branch management from file restoration. We configure fetch.prune = true globally so deleted remote branches are cleaned up automatically. When developers encounter detached HEAD states, we recover unreferenced commits using git reflog and bind them to a named branch using git switch -c <branch> <commit-hash>.