Last updated: 2026-05-18

Remote Branches and Tracking

When you work with remotes, Git maintains a parallel set of references on your local machine that mirror the state of branches on the remote. Understanding these remote-tracking branches — what they are, how they move, and how to use them — is essential for collaborating without confusion.


Remote-Tracking Branches

A remote-tracking branch is a local, read-only reference that records the state of a branch on a remote repository the last time you communicated with it.

You cannot move remote-tracking branches yourself. Git moves them automatically whenever you fetch, push, or pull — updating them to reflect the current state of the remote. Think of them as bookmarks: they tell you where a remote branch was the last time you connected to it.

Remote-tracking branch names follow the pattern <remote>/<branch>:

origin/main
origin/feature-login
upstream/develop

When you clone a repository, Git creates origin/main (or origin/master) pointing to the same commit as the remote's default branch, and creates a local main branch starting from the same point for you to work on.

After cloning:

  origin/main ──→  C3  (remote-tracking — read-only)
  main        ──→  C3  (local — you work here)

How Remote-Tracking Branches Move

Remote-tracking branches only update when Git communicates with the remote. If your teammate pushes two new commits while you are working offline, your origin/main stays where it was — it does not know about those commits yet.

Remote server:  C1 -- C2 -- C3 -- C4 -- C5  (main)

Your machine:   C1 -- C2 -- C3              (origin/main — stale)
                            \
                             D -- E          (your local main — ahead)

Running git fetch origin downloads the new commits and moves origin/main forward:

After fetch:

Remote server:  C1 -- C2 -- C3 -- C4 -- C5
Your machine:   C1 -- C2 -- C3 -- C4 -- C5  (origin/main — updated)
                            \
                             D -- E          (your local main — unchanged)

Your working branch is not touched. Only the remote-tracking reference is updated. You then decide what to do with those changes — merge, rebase, or inspect.


Pushing a Branch to a Remote

Local branches are not automatically shared. To publish a branch:

git push origin feature-login

This creates a feature-login branch on the remote and sets up origin/feature-login as its remote-tracking reference on your machine.

To push a local branch under a different name on the remote:

git push origin feature-login:new-name-on-remote

Credential caching

If you use HTTPS and are prompted for a password on every push, configure credential caching to avoid typing it repeatedly:

git config --global credential.helper cache

Tracking Branches

A tracking branch (also called an upstream branch) is a local branch that has a direct relationship with a remote-tracking branch. When you are on a tracking branch, git pull automatically knows which server to fetch from and which branch to merge into yours.

How tracking branches are created

When you clone a repository, Git automatically creates a local main branch that tracks origin/main. This is why git pull works immediately after cloning without specifying any arguments.

When you check out a local branch from a remote-tracking branch, Git sets up tracking automatically:

git checkout -b feature-login origin/feature-login
Branch 'feature-login' set up to track remote branch 'feature-login' from 'origin'.

A shorter equivalent using --track:

git checkout --track origin/feature-login

An even shorter shortcut — if the branch name doesn't exist locally and exactly matches one name on a remote, Git creates it with tracking set up automatically:

git checkout feature-login
# Branch 'feature-login' set up to track remote branch 'feature-login' from 'origin'.

Setting or changing the upstream for an existing branch

If you already have a local branch and want to set or change which remote branch it tracks:

git branch -u origin/feature-login
# or
git branch --set-upstream-to origin/feature-login

Upstream shorthand

Once tracking is set up, you can refer to the upstream branch with @{upstream} or @{u}:

git merge @{u}          # Same as: git merge origin/main
git diff @{u}           # Diff your branch against its upstream

Checking Tracking Status — git branch -vv

To see all local branches alongside what they track and how far ahead or behind they are:

git branch -vv
  feature-login  93b412c [origin/feature-login: ahead 2] Add form validation
* main           7a98805 [origin/main] Merge branch 'feature-login'
  experiment     5ea463a (no upstream set)

Reading the output:

ColumnMeaning
*The currently checked-out branch
HashThe abbreviated SHA-1 of the last commit on that branch
[origin/branch]The remote-tracking branch it follows
ahead NN local commits not yet pushed to the remote
behind NN remote commits not yet pulled into the local branch
No bracketsNo upstream tracking branch configured

Important: git branch -vv shows cached data from the last fetch. For current numbers, run git fetch --all first:

git fetch --all && git branch -vv

Deleting Remote Branches

Once a branch is merged and no longer needed on the remote:

git push origin --delete feature-login

This removes the branch pointer from the remote server. The commits themselves are not immediately deleted — they remain in the database until garbage collection runs, which means an accidental deletion can often be recovered.

Cleaning up stale remote-tracking references

After remote branches are deleted, their local remote-tracking references may linger. Clean them up with:

git fetch --prune

Or configure Git to prune automatically on every fetch:

git config --global fetch.prune true

How Everything Fits Together

Here is the relationship between the three types of references involved in remote collaboration:

Reference typeExampleWho controls itPurpose
Local branchmainYou — moves with your commitsWhere you do your work
Remote-tracking branchorigin/mainGit — updates on fetch/push/pullBookmark of the remote's last known state
Remote branchmain on originThe remote serverThe actual shared branch

When you git fetch, the remote-tracking branch moves to match the remote branch. When you git push, the remote branch moves to match your local branch. The two never automatically synchronise — you are always in control of when synchronisation happens.


Summary

CommandWhat It Does
git fetch originUpdates all remote-tracking branches from origin
git fetch --allUpdates remote-tracking branches from all remotes
git fetch --pruneUpdates and removes stale remote-tracking references
git push origin <branch>Publishes a local branch to the remote
git push -u origin <branch>Publishes and sets up tracking
git push origin --delete <branch>Deletes a remote branch
git checkout --track origin/<branch>Creates a local tracking branch
git branch -u origin/<branch>Sets the upstream for the current branch
git branch -vvShows tracking info and ahead/behind counts