How can I see which Git branches are tracking which remote / upstream branch?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Run git branch -vv to see every local branch alongside its upstream tracking branch, latest commit, and ahead/behind status. This is the fastest single command to answer "what tracks what" across your entire repository.
Branches with [origin/...] have an upstream configured. The stale branch in this example has no upstream, meaning it is a purely local branch. The rest of this article covers every method for inspecting tracking relationships, how to set or change them, and how to diagnose common misconfigurations.
Understanding Tracking Relationships
A tracking relationship links a local branch to a remote-tracking reference (like origin/main). When this relationship exists, Git provides three conveniences:
git pullknows which remote branch to fetch and merge without you specifying it.git pushknows where to push without explicit arguments (depending onpush.defaultconfig).git statusshows "ahead N / behind M" relative to the upstream.
Without a tracking relationship, you must specify the remote and branch explicitly for push and pull operations.
Tracking is stored in .git/config as two entries per branch:
The remote value identifies which remote to interact with, and merge identifies which branch on that remote.
Method 1: git branch -vv
This is the go-to command for a quick overview:
The output columns are:
| Column | Meaning |
| Branch name | Your local branch |
| Commit hash | Latest commit on that branch |
[remote/branch] | The upstream tracking branch (if configured) |
| Ahead/behind status | How many commits differ from the upstream |
| Commit subject | First line of the latest commit message |
To include remote-tracking branches in the listing:
This adds lines like remotes/origin/main to the output, showing all references in the repository.
Method 2: git remote show <remote>
For detailed information about a specific remote, including which local branches track which remote branches:
This command contacts the remote to check status, so it requires network access. It is particularly useful when you work with multiple remotes (e.g., origin and upstream in a fork workflow) and want to see the full picture for one remote at a time.
Method 3: git config Queries
You can query tracking information for a specific branch directly from the Git config:
To list all branch tracking entries at once:
This is useful in scripts where you need to programmatically determine tracking relationships.
Method 4: git for-each-ref
For machine-parseable output, git for-each-ref with a custom format is the most reliable option:
Branches without an upstream show an empty value after the arrow. This format is ideal for piping into other tools or scripts:
You can also include ahead/behind counts:
Method 5: Inspecting .git/config Directly
The raw configuration file shows tracking relationships in their stored form:
Look for [branch "..."] sections:
This is the source of truth that all other commands read from. Editing it manually is possible but error-prone; use git branch --set-upstream-to instead.
Comparison of Methods
| Method | Network Required | Machine Parseable | Shows All Branches | Shows Ahead/Behind |
git branch -vv | No | No | Yes | Yes |
git remote show <remote> | Yes | No | Per remote | Yes |
git config --get-regexp | No | Yes | Yes | No |
git for-each-ref | No | Yes | Yes | Yes (with format) |
cat .git/config | No | No | Yes | No |
Setting and Changing Upstream Tracking
Setting Upstream on an Existing Branch
Setting Upstream During Push
When pushing a new branch for the first time, use -u to set the upstream simultaneously:
This creates the remote branch and configures the local branch to track it in one step.
Removing an Upstream
To unset a branch's tracking relationship:
After this, git branch -vv will no longer show a tracking reference for that branch.
Changing to a Different Remote
If you need to switch a branch from tracking origin to tracking upstream (common in fork workflows):
Diagnosing Common Tracking Issues
"Your branch is based on 'origin/feature', but the upstream is gone"
This means the remote branch was deleted but your local tracking reference still points to it. Fix it by updating remote references and optionally resetting the upstream:
Push Rejected Despite Tracking Being Set
If push.default is set to simple (the default since Git 2.0), Git refuses to push if the local branch name differs from the remote branch name, even with a tracking relationship. Either rename the local branch or set the push config:
No Tracking After Clone
Normally, git clone sets up tracking for the default branch automatically. If other branches are not tracking, it is because Git only creates tracking for the branch you check out, not for all remote branches. To check out and track a remote branch:
Common Pitfalls
Assuming all branches track automatically. Only the branch created by git clone or checked out from a remote has automatic tracking. New branches created with git checkout -b from a local ref do not track anything by default.
Confusing remote-tracking branches with remote branches. A "remote-tracking branch" like origin/main is a local reference that caches the state of the remote. It is updated by git fetch, not in real time. The actual remote branch may have moved since your last fetch.
Forgetting to fetch before checking status. The ahead/behind count shown by git branch -vv is based on the last git fetch. If you have not fetched recently, the numbers may be stale. Run git fetch --all first for accurate counts.
Using git remote show in scripts. This command contacts the remote over the network, which makes it slow and unreliable in automated pipelines. Use git for-each-ref or git config queries instead.
Editing .git/config by hand. While it works, manually editing branch tracking entries is error-prone. A typo in the merge ref will silently break tracking. Use git branch -u for safe modifications.
Summary
git branch -vvis the fastest way to see all tracking relationships interactively.git remote show originprovides a detailed view per remote but requires network access.git for-each-refandgit config --get-regexpare the best choices for scripting.- Set upstream tracking with
git branch -uorgit push -uwhen pushing a new branch. - Remote-tracking branches are local caches updated by
git fetch, not live mirrors. - Always fetch before relying on ahead/behind counts for accuracy.

