Skip to content
masterclass Buddy

Git · Command

git remote

git remote manages the named remote repositories your local repository tracks. You use it to list, add, rename, remove and inspect remotes and their URLs and tracked branches.

Last updated

How it works

A remote is a short name, like origin, saved in the repository config. It mainly lives in remote.<name>.url and a remote.<name>.fetch refspec. Running git remote with no arguments lists the configured names. Subcommands change that config. add creates an entry, and git fetch <name> then fills in remote-tracking branches under refs/remotes/<name>/. rename and remove update or delete those refs together with the config. set-url, set-branches and set-head change the URL, the fetch refspec and the default branch. show, prune and update contact the remote to report on it, clean up stale refs or fetch.

Syntax

git remote [-v | --verbose]
git remote add [-t <branch>] [-m <master>] [-f] [--[no-]tags] [--mirror=(fetch|push)] <name> <URL>
git remote rename [--[no-]progress] <old> <new>
git remote remove <name>
git remote set-head <name> (-a | --auto | -d | --delete | <branch>)
git remote set-branches [--add] <name> <branch>...
git remote get-url [--push] [--all] <name>
git remote set-url [--push] <name> <newurl> [<oldurl>]
git remote [-v | --verbose] show [-n] <name>...
git remote prune [-n | --dry-run] <name>...
git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]

Parameters

NameTypeDescription
-v, --verboseflagShows each remote's URL after its name. For promisor remotes it also shows the configured filters. It must come before the subcommand.
<name>stringThe short name of a remote, such as origin.
<URL>stringWhere the remote repository lives. Used by add, and by set-url --delete as a regex.
-t <branch>string (repeatable)Used with add. Tracks only the named branch or branches instead of the default glob refspec.
-m <master>stringUsed with add. Points refs/remotes/<name>/HEAD at the given branch on the remote.
-fflagUsed with add. Runs git fetch <name> right after the remote is set up.
--[no-]tagsflagUsed with add. Makes fetch import every tag, or no tags at all.
--mirror=(fetch|push)enumUsed with add. Creates a fetch mirror (mirrors refs/ directly) or a push mirror (push always behaves as if --mirror were given).
--push / --add / --delete / --allflagModifiers for get-url and set-url. They choose push URLs instead of fetch URLs, add or delete URLs, or list every URL.
-n, --dry-runflagWith show, uses cached info instead of querying the remote. With prune, only reports what would be pruned.

Returns

Exit status 0 on success. If add, rename or remove cannot find the remote, the status is 2. If the remote already exists, it is 3. Any other error gives some other non-zero value.

Key points

  • Renaming a remote also renames its remote-tracking branches and config entries, so you don't have to fix refs by hand.
  • rm is an alias for remove. Removing a remote deletes its remote-tracking branches as well as its config entries.
  • A remote can have more than one URL. get-url prints only the first one unless you pass --all.
  • prune works like fetch --prune but downloads nothing. With --dry-run it only reports what it would remove.
  • When you add a remote, fetch brings in only the tags on fetched branches unless you pass --tags or --no-tags.
  • You can pass -t several times to track only selected branches. set-branches changes that list later.
  • set-head sets refs/remotes/<name>/HEAD, which lets you type just the remote name, such as origin, wherever you would type origin/<branch>.
  • Scripts can check for exit status 3 to detect an add that failed because a remote with that name already exists.

Common mistakes

  • The push URL and fetch URL must point to the same repository. If you want to fetch from upstream and push to a fork, set up two remotes instead.
  • Only use --mirror=fetch in bare repositories. In a repository with a working tree, a fetch can overwrite your local commits.
  • set-head with an explicit branch, or with --auto, fails if that remote-tracking ref hasn't been fetched yet.
  • Depending on your config, prune may also delete local tags that were never pushed to that remote.

Example: Add an upstream remote, inspect it, and clean up

#!/usr/bin/env bash
set -euo pipefail

# Add the original project as 'upstream' and fetch it immediately
git remote add -f upstream https://example.com/project/repo.git

# List remotes with their URLs
git remote -v

# Switch origin to SSH
git remote set-url origin git@example.com:me/repo.git
git remote get-url --all origin

# Point upstream/HEAD at whatever the remote's default branch is
git remote set-head upstream --auto

# Preview, then delete stale remote-tracking branches
git remote prune --dry-run upstream
git remote prune upstream

# Fetch all remotes and prune in one go
git remote update --prune

This script shows a typical fork workflow: add an upstream remote, change origin's URL, set upstream's default branch, and remove stale refs.

When to use it

Contributing to a fork

Clone your fork as origin and add the original project as upstream. You can then fetch upstream changes and push your work to origin.

Moving hosting or switching protocol

After a repository moves, or when you switch from HTTPS to SSH, update the stored address with set-url. Your branches and tracking setup stay as they are.

Tracking only a few branches of a large repo

Use add -t or set-branches to limit the fetch refspec to the branches you need. This avoids downloading every branch.

Cleaning up after merged PRs

Run prune, or update --prune, to remove remote-tracking branches whose branches were deleted on the server.

Interview questions

QWhat happens under the hood when you run git remote add origin <URL>?

Git writes a remote section to the repository config: remote.origin.url and a default fetch refspec covering every branch under refs/remotes/origin/. Nothing is downloaded unless you pass -f. A later git fetch origin creates and updates the origin/<branch> remote-tracking refs.

Follow-up: How would you add a remote that fetches only main and dev? Use git remote add -t main -t dev <name> <URL>. Each -t creates a refspec for that branch only, instead of the default glob.

QHow do git remote prune and git fetch --prune differ?

Both remove remote-tracking refs whose branches no longer exist on the remote. prune does not fetch any new objects or refs, while fetch --prune also downloads updates. prune --dry-run shows what it would delete without deleting it.

Follow-up: Can pruning delete more than remote-tracking branches? Yes. Depending on global and per-remote config, it can also delete local tags that were never pushed to that remote.

QCan one remote fetch from one repository and push to another?

You can set a separate push URL with set-url --push, but the docs require both URLs to point to the same repository. Fetching right after a push should show what you just pushed. To fetch from upstream and push somewhere else, define two separate remotes.

Follow-up: What does git remote set-url --delete do if the pattern matches every fetch URL? Git reports an error, because removing all non-push URLs is not allowed.

  • git fetch
  • git push
  • git pull
  • git branch
  • git config
  • git clone
  • git ls-remote

Source: Git - git-remote Documentation. Checked 2026-11-02.