Git Worktree: Track an Existing Remote Branch
Prepared and checked using AI. Sources are linked in the article.
To add a Git worktree for an existing remote branch without ending up on a detached HEAD, fetch the remote and create a local branch in the new worktree. For example, if origin/feature/login exists and there is no local feature/login yet, run git fetch origin followed by git worktree add --track -b feature/login ../repo-login origin/feature/login. The worktree -b option creates and checks out the local branch; --track makes the remote-tracking branch its upstream.
Create the worktree from the remote branch
Run these commands from your existing repository. Here, origin is the remote, feature/login is the branch name, and ../repo-login is the new worktree path:
git fetch origin
git branch -r --list origin/feature/login
git branch --list feature/login
git worktree add --track -b feature/login ../repo-login origin/feature/login
Fetching origin updates its remote-tracking branches according to the remote’s configured fetch refspec. Check that origin/feature/login appears before creating the worktree. The local branch check matters too: -b refuses to create a branch whose name already exists. If feature/login appears in that check, use the existing-branch instructions below.
The two branch names in the final command have different jobs. feature/login after -b is the local branch Git creates and checks out. origin/feature/login at the end is the starting point and upstream. The worktree path only chooses where files are checked out; it does not need to match either branch name.
Tracking means Git records which remote branch the local branch builds on. It does not make the two branches move together automatically. A later fetch can advance origin/feature/login while your local feature/login stays at its own commit until you integrate the fetched changes. That distinction matters when an agent is working in the new directory: fetching updates your view of the remote, while changing the agent’s checked-out branch is a separate step.
Verify the branch and upstream
Enter the new worktree and check both pieces of state:
cd ../repo-login
git branch --show-current
git rev-parse --abbrev-ref --symbolic-full-name '@{upstream}'
git branch -vv
The first command should print feature/login. The second should print origin/feature/login: @{upstream} names the current branch’s configured upstream. Keep the quotes around it so the shell passes the expression to Git.
git branch --show-current prints nothing when HEAD is detached. git branch -vv gives a broader check: it shows local branches, their upstream relationships, and the path of a linked worktree when applicable. You can also run git worktree list from either worktree to see which branch is checked out at each path. A branch name in the worktree list confirms an attached HEAD; the upstream check confirms tracking. You need both answers.
If the upstream command fails, the branch can still be checked out normally; it simply lacks the upstream you intended. From inside the new worktree, set it explicitly:
git branch --set-upstream-to=origin/feature/login
git rev-parse --abbrev-ref --symbolic-full-name '@{upstream}'
This changes tracking information for the current branch. It does not reset the branch or replace its files.
If the local branch already exists
A remote branch may already have a corresponding local branch. In that case, leave out -b and supply the local branch name:
git worktree list
git worktree add ../repo-login feature/login
This checks out the existing local feature/login in the new worktree. Its upstream configuration comes along with that branch, so verify it with the commands above. If it points to a different remote branch, set the intended upstream inside the new worktree with git branch --set-upstream-to=origin/feature/login.
If Git says feature/login is already checked out, use git worktree list to find where. Git normally refuses to check out the same local branch in two worktrees; forcing that checkout bypasses a useful safeguard. Work in the existing directory, move that worktree, or create a different local branch if you need concurrent work. The branch-already-checked-out guide covers those choices.
Avoid substituting -B for -b just to get past an existing-branch error. -B resets the named branch to the supplied starting point. That changes a branch which may contain local commits; it does not solve the problem of two worktrees wanting the same branch.
Why the remote name can leave HEAD detached
origin/feature/login is a remote-tracking ref, not the local branch you intend to commit on. A command such as git worktree add ../repo-login origin/feature/login names that ref as the checkout target but never asks Git to create a local branch. If the resulting worktree shows (detached HEAD) in git worktree list, HEAD points directly to a commit rather than to feature/login. Git’s detached-HEAD explanation describes that distinction.
If you already made commits in a detached worktree, create a branch at the current HEAD before doing anything that changes the checkout:
cd ../repo-login
git checkout -b feature/login
git branch --set-upstream-to=origin/feature/login
This sequence keeps the detached worktree’s current commit as the new branch tip, then sets its upstream. It requires that no local feature/login exists. If the local name is already taken, choose another branch name first and decide separately how to integrate its commits. Creating a new branch directly at origin/feature/login would start at the remote-tracking tip instead of at any commits made while detached.
For a directory used only to inspect a commit, a detached HEAD may be exactly what you want. For an AI coding agent expected to commit changes and keep working on a named branch, create or check out a local branch deliberately. The broader Git worktrees overview explains how linked worktrees share a repository while keeping separate working files.
When Git’s shortcuts are safe
You can sometimes omit -b, --track, and the remote prefix:
git worktree add ../repo-login feature/login
If there is no local feature/login and exactly one remote has a matching remote-tracking branch, Git treats this as a request to create a local tracking branch. If a local branch already exists, Git uses that branch instead. The explicit command in the first section is easier to reason about when several remotes contain the same branch name or when you need to confirm which starting point was used.
Another shortcut is git worktree add <path> with no branch argument. Git uses the final component of the path as the branch name; if that local branch does not already exist, Git creates it from the current HEAD. If it exists, Git checks it out unless it is already checked out in another worktree, in which case the command refuses. This is convenient for a new task, but it does not express a request to open an existing remote branch. git worktree add --guess-remote <path> instead looks for a remote-tracking branch matching that path component; when no match exists and the local branch does not already exist, it falls back to creating a branch from HEAD. Check the chosen branch and upstream afterward.
If your team regularly has the same branch names on multiple remotes, checkout.defaultRemote can select a preferred remote during Git’s branch-name guessing. For a single command whose remote matters, spelling out origin/feature/login avoids relying on that configuration. It also makes the intended upstream visible to anyone reviewing the command.
When the remote branch is missing
If git branch -r --list origin/feature/login prints nothing after a fetch, first confirm the remote name and branch spelling. A repository’s configured fetch refspec determines which remote refs git fetch origin stores under refs/remotes/origin/. A narrowed refspec can leave a branch unlisted even though it exists on the server. Inspect that configuration before treating the missing local remote-tracking ref as proof that the server branch is gone.
A remote-tracking ref can also be stale after a branch was deleted on the server. When that distinction matters, git fetch --prune origin removes stale remote-tracking refs according to the configured refspec while fetching. Review unusual refspecs before using pruning, especially ones that map tags into the local tag namespace. Do not create a worktree from a stale origin/feature/login merely because the name still appears locally.
Where Parallel Code fits
Parallel Code is our free, open-source (MIT) desktop app for macOS and Linux that runs AI coding agents in parallel, each in its own Git worktree. It provides a diff-first review surface and launches the agent CLIs you already use locally, so this branch and upstream check remains useful before assigning work to an agent.
Frequently asked questions
Does git worktree add automatically track a remote branch?
It can when you provide a missing local branch name that matches a remote-tracking branch in exactly one remote. Use --track -b <local-branch> <path> <remote>/<branch> when you want to state the branch and upstream explicitly, then verify them inside the worktree.
Why does git worktree add say the branch is already checked out?
The local branch is attached to another worktree, which git worktree list will show. Open that worktree or create a different local branch for simultaneous work; giving both directories the same branch name defeats Git’s normal checkout safeguard.
Can I fix a detached worktree without losing commits?
Yes, if the desired local branch name is unused: create it from the current detached HEAD with git checkout -b <branch>, then set its upstream with git branch --set-upstream-to=<remote>/<branch>. Creating the branch at the current HEAD is the key step when commits were made while detached.
Does setting an upstream pull the latest remote commits?
No. Upstream configuration records the branch relationship used by commands such as git pull; it does not itself fetch or integrate commits. Fetch the remote and decide how to integrate any new commits into your local branch.