Git

What Is Git Remote? Manage Connections Easily

What Is Git Remote? Manage Connections Easily

Git has no memory for server addresses. Every fetch, pull and push needs one, and git remote is the command that attaches a short name to a URL so you can type the name instead.

A fresh clone has exactly one such entry, origin. Teams on GitHub or GitLab pile on more for forks and mirrors.

The entry is only a name and a URL, with a default fetch refspec stored alongside them in .git/config. Nothing executable is attached.

The add subcommand contacts no server unless -f is passed (git-remote manual, Git 2.53.0, 2026). A mistyped URL goes unnoticed until the first fetch or push.

What Is git remote?

YouTube player

The Pro Git book describes a remote as a version of your project hosted on the internet or another network. It doesn’t have to be far away, since a path on the same machine counts too.

git remote manages the named shortcuts that link your local repository to those URLs. The name stands in for the full address in fetch, pull and push.

A remote is a reference, not a copy of the code. The remote repository on the other end holds the commits, and the remote entry only points to it.

Each remote has a shortname like origin or upstream and a URL, which can be HTTPS, SSH, git:// or a plain filesystem path. The refspec sits behind both and decides which remote branches Git tracks locally.

Git calls the server you cloned from origin by default. You never picked that name, because cloning a repository creates it automatically.

Run git remote with no arguments in any fresh clone and it prints origin.

Why is GitHub the heart of open source?

Uncover GitHub statistics: developer community growth, repository trends, collaboration patterns, and the platform that powers modern software development.

Explore GitHub Data →

Git doesn’t care which host is behind it. GitHub, GitLab, Bitbucket, Azure DevOps or a self-hosted Gitea server all look the same to it, since a remote is just a name and a URL.

How Does Git Store a Remote in the Repository?

YouTube player

Inside .git/config. Each remote gets a [remote "name"] section with a url key and a fetch refspec key, and the git remote command edits that file so you don’t have to.

A fresh clone writes this entry for the default origin remote:

[remote "origin"]
url = https://github.com/OWNER/REPOSITORY.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/main

The section header names the remote, and url holds the address used for both fetch and push. The fetch line holds the refspec. The branch block at the bottom records which remote the local main branch pulls from.

The Git documentation lists these as the variables remote.origin.url and remote.origin.fetch, and the git config command reads and writes them directly.

Looking to sharpen your Git skills? Branching, merging, rebasing, and everything else you need - including git rebase, git stash, and commit workflows - is on one page in the Git Cheat Sheet.

What the fetch line controls

YouTube player

The refspec has two sides. On the left, refs/heads/* matches every branch on the server. On the right, refs/remotes/origin/* is where Git records them locally.

The leading plus sign lets Git update a local reference even when the update is not a fast-forward (Pro Git).

To track one branch instead of all of them, pass -t when adding the remote. The git-remote manual (Git 2.53.0, February 2026) says this replaces the default glob with a refspec for that single branch.

Since Git 2.6.0 the pattern also accepts partial globs such as qa*.

Where remote settings do not travel

The config file stays inside your clone. Pushing never copies remote definitions, so every teammate’s clone starts with its own origin.

▶ GIT EXPLAINED

If you commit, branch, or merge code every day, it helps to know how Git came to be. This video covers how Linus Torvalds created Git in just 10 days after a license dispute and explains how its data model actually works.

Linus Torvalds Built Git in Days Out of Spite
Built in 10 Days Out of Spite. Git and its data model explained in plain language.

Which git remote Subcommands Manage Remotes?

YouTube player

Day to day you’ll mostly touch add, rename, remove, set-url, get-url, show and prune. Only show and prune contact the server by default. The manual also lists set-head, set-branches and update, and update does fetch from the server.

SubcommandSyntaxEffectContacts server
addgit remote add NAME URLWrites a new remote sectionNo (yes with -f)
renamegit remote rename OLD NEWRenames the remote and its tracking branchesNo
removegit remote remove NAMEDeletes the section and its tracking branchesNo
set-urlgit remote set-url NAME NEWURLChanges the stored URLNo
prunegit remote prune NAMEDeletes stale tracking branchesYes

Adding and Changing a Remote

Add writes config and nothing else. Pass -f and Git runs a fetch right away.

Rename carries all remote-tracking branches over to the new name, so pb/master becomes paul/master (Pro Git).

Changing a URL is set-url’s job. It swaps the first matching URL, and with --push it changes only the push URL. If the old URL you pass matches nothing, the command errors and changes nothing.

Fetch and push URLs must still refer to the same place. To fetch from one repository and push to another, the manual says to use two separate remotes.

Scripts can read the exit codes. A name that already exists returns status 3, while a missing remote in rename or remove returns status 2. The familiar “remote origin already exists” error is the first case.

Inspecting and Cleaning Up Remotes

With no arguments, git remote lists names. Add -v and each remote shows one fetch URL and one push URL.

get-url NAME prints the URL with insteadOf rewrites applied, and --push prints the push URL instead.

show NAME reports the HEAD branch, tracked and stale branches, and the pull and push configuration, but only after querying the server (-n skips the query). prune NAME does the same job as git fetch --prune NAME without fetching anything new.

show flags branches deleted on the server as stale, which is the cue to run prune.

Use prune --dry-run first on a repository you do not recognize.

HTTPS or SSH: Which Remote URL Should You Use?

Use HTTPS when a firewall or a shared machine makes key setup awkward. CI runners usually land here too. On your own machine, SSH is nicer if you push often. Both are authenticated and encrypted.

ProtocolURL formatAuthenticationBest fit
HTTPShttps://host/owner/repo.gitToken or credential helperFirewalled networks, CI, quick setup
SSHgit@host:owner/repo.gitSSH keyFrequent pushes from a trusted machine
git://git://host/owner/repo.gitNonePublic read-only serving, rarely
Local path/srv/git/project.gitFile permissionsShared filesystem on one host

GitHub stopped accepting account passwords for Git operations on August 13, 2021 (GitHub Blog). Token or SSH key authentication is required since then.

On HTTPS, you generate a GitHub token and paste it where Git asks for the password. Git Credential Manager can store it so the prompt does not return.

For SSH, start with adding an SSH key to your GitHub account. Skip it and the push ends in a “Permission denied (publickey)” error.

Pro Git adds that corporate firewalls often allow HTTP and HTTPS traffic, which is why HTTPS tends to work where other transports fail.

On HTTPS the old account password is rejected on GitHub, so a token is mandatory. SSH has no anonymous access, which means even read-only cloners need SSH access to the host.

git:// has no authentication or encryption, and port 9418 is often blocked. Pro Git warns that cloning over it can lead to arbitrary code execution if traffic is tampered with.

Local paths use hardlinks or direct copies, while file:// runs the slower network transfer. Either way, the local protocol does not protect the repository from accidental damage.

Switching an existing remote between protocols

Change the URL in place instead of removing and re-adding the remote. From HTTPS to SSH:

git remote set-url origin git@github.com:OWNER/REPOSITORY.git

From SSH back to HTTPS:

git remote set-url origin https://github.com/OWNER/REPOSITORY.git

Confirm the change with git remote -v. Remote-tracking branches and branch settings stay intact.

How Do Fetch, Pull and Push Use a Remote?

YouTube player

Clone is what creates the entry in the first place. After that, fetch downloads, pull downloads and then merges, and push sends your commits up.

Name no remote and fetch and push use the branch’s upstream, or origin when none is set, according to the Git manuals.

Remote-tracking branches

Git keeps a local reference recording where a remote branch stood the last time you talked to the server. It lives under refs/remotes, for example refs/remotes/origin/main, usually shortened to origin/main.

The remote branch itself sits on the server and moves only when someone pushes. origin/main in your repository is its remote-tracking counterpart, which fetch and pull move. Then there’s plain main, the local branch you commit to.

Local commits never move origin/main. Only contact with the server does.

Fetch or pull

Fetch downloads new commits and moves the remote-tracking branches, leaving your working files and local branches alone (Pro Git).

Pull runs that fetch, then merges the tracked remote branch into the branch you have checked out.

Under the hood, a pull is exactly that two-step sequence with no pause in between.

Since Git 2.27, pull warns until pull.rebase is set. Set it to false to keep merge behavior or true to rebase (Pro Git).

Fetch first on a shared branch when you want to read what changed before merging. Plain pull is fine on a branch only you touch.

Upstream tracking and automatic pruning

The first push of a new branch is usually where tracking gets set.

  • git push -u origin main adds the upstream reference that argument-less pull and push read
  • push.autoSetupRemote set to true does the same on the first push of a branch that has no upstream yet (with push.default set to simple, upstream or current)
  • push.default has been simple since Git 2.0, which pushes to the same-named branch
  • Setting fetch.prune or remote.NAME.prune makes every fetch drop stale remote-tracking branches

Pruning follows the remote’s refspec, not branch names. If the refspec includes refs/tags/*:refs/tags/*, prune deletes local tags missing from the remote instead, per the git-fetch manual for Git 2.56.0 (September 2026).

How Do Multiple Remotes Work With origin and upstream?

YouTube player

In a fork workflow, origin is your fork and upstream is the original repository. You fetch from upstream and push to origin.

Git gives the name upstream no special meaning, because only origin is created automatically. It is a convention, and the upstream remote pattern exists because a fork on GitHub is a separate repository you can write to, while the original is one you usually cannot.

  1. Fork the project on the host, then clone your fork. Git names it origin.
  2. Run git remote -v and confirm origin lists your fork for fetch and push.
  3. Run git remote add upstream followed by the original repository URL.
  4. Run git remote -v again. Four lines appear, fetch and push for each remote.
  5. Run git fetch upstream to create the upstream/main remote-tracking branch (or the project’s default branch).
  6. Switch to main and run git merge --ff-only upstream/main.
  7. Run git push origin main to publish the synced branch to your fork.

Steps 2 to 4 follow the GitHub Docs procedure for configuring a remote for a fork. The fast-forward flag in step 6 makes the merge fail instead of creating a merge commit when your main has diverged from upstream.

Cloned the original first and forked later? Rename the existing remote, then add your fork under the old name (Happy Git with R):

git remote rename origin upstream

git remote add origin git@github.com:YOUR-USERNAME/YOUR-FORK.git

Two remotes is not the ceiling. The git-remote manual’s own example adds a staging remote from a kernel.org tree and fetches three branches from it, and Pro Git’s grit example lists five.

Pushing to several remotes at once

The git-push manual (updated in Git 2.55.0, June 2026) documents remote groups, a named list set with git config remotes.all-remotes "origin gitlab backup". Then git push all-remotes pushes to each member in turn.

Each push runs independently. A failure on one member does not stop the rest, but the overall exit code is non-zero.

Group pushes refuse --atomic, because atomicity holds only within a single connection to a single remote.

Why Do git remote Commands Fail?

YouTube player
MessageCauseFix
fatal: remote origin already existsA remote with that name is already configuredUse set-url to repoint it, or rename the old remote first
fatal: not a git repositoryCommand run outside a repositoryChange into the repository root and retry
remote: Repository not foundWrong URL, or no access to a private repositoryCheck git remote -v, correct the URL, confirm credentials
Permission denied (publickey)SSH offered no key the host acceptsRun ssh -vT git@github.com, load the key, add the public key to the account
! [rejected] (non-fast-forward)The remote branch has commits you do not haveFetch, merge or rebase, then push again

On GitHub, SSH connections must use the “git” user, per GitHub Docs. A remote URL containing your account name fails with the same publickey error, and set-url fixes it.

Rejected versus remote rejected

Rejected means Git refused to send the update, usually because it is not a fast-forward. Rebasing your commits onto the fetched work, or merging it, makes the push fast-forward.

Remote rejected means the server refused the update, typically through a hook or a safety option such as receive.denyCurrentBranch or receive.denyNonFastForwards (git-push manual).

The receive.denyCurrentBranch safeguard explains why shared remotes are usually a bare repository. With no checked-out branch, nothing is there to protect.

Prefer --force-with-lease over --force when you must overwrite history. It fails if the remote branch moved since you last looked, though a background fetch can defeat that check.

git remote FAQ

Can a Git repository work without any remote?

Yes. Commits, branches, merges and history all work locally, and git remote simply prints nothing in a repository that has none.

A remote only becomes necessary when you want to share work or keep an off-machine copy.

Is a Git remote the same thing as GitHub?

YouTube player

No. GitHub is one host, while the remote is the named URL stored in your repository’s config.

The same remote entry can point at GitLab, Bitbucket, a self-hosted server or a folder on disk.

Does removing a remote delete my code?

No. git remote remove deletes the config entry and the matching remote-tracking branches, according to the git-remote manual.

Your local branches and commits stay, and the repository on the server is untouched.

What is a bare repository, and why do servers use one?

Pro Git defines a bare repository as one that holds only the contents of a .git directory and has no working directory.

Nobody edits files on a shared server, so there is no checkout to keep in sync, and pushes to a checked-out branch are refused by default.

How can I see which remote branch a local branch tracks?

Run git branch -vv. Each local branch is listed with its upstream in square brackets.

git status adds how many commits the branch is ahead of or behind that upstream.

How to Verify a New Remote Before Relying on It

A new git remote earns trust through a read-only call, not through a successful add. git ls-remote NAME lists the references on the server and fails at once on a wrong URL or rejected credentials.

Run the checks in this order, cheapest first:

  • git remote -v to read the stored URLs
  • git ls-remote NAME to test reachability and login
  • git push --dry-run to rehearse the upload

ls-remote proves read access only, so a read-only token passes the second check and can still fail on the first real push.

Position verified against the Git 2.56 manuals (September 2026). Rerun the check on any remote untouched for months, since hosts change authentication rules.

With the checks passed, pushing your first commits to GitHub is the natural next step.

Bogdan Sandu

Stay sharp. Ship better code.

Every week: one curated article, one tool worth knowing, one tip you can use tomorrow. No noise, no padding.