Ad – 728×90
🌐 Remote Repositories

Git Remotes – origin, upstream, and Remote Management

Up to now, Git has been entirely local — your commits exist only on your machine. Remotes connect your local repo to copies hosted elsewhere: GitHub, GitLab, Bitbucket, or your own server. Understanding how remotes work — what "origin" means, what "tracking branches" are — is the bridge between local Git and collaborative development.

⏱️ 15 min read 🎯 Beginner 📅 Updated 2026

What Is a Git Remote?

A remote is simply a named URL pointing to another copy of the repository. That copy might be on GitHub, GitLab, Bitbucket, a company server, or even another folder on your own machine.

Git stores remotes as name-URL pairs in .git/config:

text
# Inside .git/config
[remote "origin"]
    url = https://github.com/username/my-repo.git
    fetch = +refs/heads/*:refs/remotes/origin/*

[remote "upstream"]
    url = https://github.com/original-author/my-repo.git
    fetch = +refs/heads/*:refs/remotes/upstream/*

Remotes let you push (upload) your commits to the remote, and fetch/pull (download) commits others have pushed. The remote repo doesn't need to be online for you to work locally — Git only contacts it when you explicitly push, fetch, or pull.

What Is "origin"?

origin is just a conventional name — nothing more. When you run git clone <url>, Git automatically creates a remote called origin pointing to the URL you cloned from. You could rename it to anything, but origin is the universal convention that every tool and tutorial expects.

Shell
# git clone automatically creates the "origin" remote
git clone https://github.com/username/my-repo.git
cd my-repo

git remote -v
# origin  https://github.com/username/my-repo.git (fetch)
# origin  https://github.com/username/my-repo.git (push)
ℹ️
Why "origin"?

When you fork a repo and clone your fork, "origin" refers to YOUR fork (because that's what you cloned). The original repository you forked from is conventionally named "upstream". This two-remote setup is standard for open-source contribution workflows.

Adding Remotes

If you initialised a repo with git init (rather than cloning), there's no remote yet. You add one manually:

Shell
# Add the primary remote (your repo on GitHub)
git remote add origin https://github.com/username/my-repo.git

# Add upstream (the original repo you forked from)
git remote add upstream https://github.com/original-author/my-repo.git

# Verify remotes were added
git remote -v
# origin    https://github.com/username/my-repo.git (fetch)
# origin    https://github.com/username/my-repo.git (push)
# upstream  https://github.com/original-author/my-repo.git (fetch)
# upstream  https://github.com/original-author/my-repo.git (push)
Ad – 336×280

Listing Remotes

Shell
# List remote names only
git remote
# origin
# upstream

# List remotes with their URLs (fetch and push URLs)
git remote -v
# origin    git@github.com:username/my-repo.git (fetch)
# origin    git@github.com:username/my-repo.git (push)
# upstream  git@github.com:original/my-repo.git (fetch)
# upstream  git@github.com:original/my-repo.git (push)

# Detailed info about a specific remote
git remote show origin
# * remote origin
#   Fetch URL: git@github.com:username/my-repo.git
#   Push  URL: git@github.com:username/my-repo.git
#   HEAD branch: main
#   Remote branches:
#     main tracked
#     feature/login tracked
#   Local branch configured for 'git pull':
#     main merges with remote main

Renaming and Removing Remotes

Shell
# Rename a remote
git remote rename origin backup
git remote rename backup origin   # rename back

# Remove a remote (just removes the local reference — doesn't delete anything on GitHub)
git remote remove upstream

# Change a remote's URL (e.g., switching from HTTPS to SSH)
git remote set-url origin git@github.com:username/my-repo.git

Tracking Branches

When you fetch from a remote, Git creates remote-tracking branches — local read-only copies that record what each remote branch looked like the last time you fetched. They're named <remote>/<branch>: for example, origin/main or origin/feature/login.

Shell
# After git fetch, list all branches including remote-tracking
git branch -a
# * main
#   remotes/origin/main
#   remotes/origin/feature/login

# See how far ahead/behind your local branch is from the remote
git status
# On branch main
# Your branch is behind 'origin/main' by 2 commits, and can be fast-forwarded.

# Compare local main to origin/main
git log main..origin/main --oneline
# Shows commits on origin/main that you don't have locally
ℹ️
origin/main is a snapshot, not live

origin/main only updates when you explicitly run git fetch or git pull. If a teammate pushed new commits to GitHub 5 minutes ago, your local origin/main doesn't know about them until you fetch. This is intentional — Git never contacts the network without your permission.

Remote nameConventionSet by
origin Your primary remote (the repo you cloned or your fork) Auto-set by git clone
upstream The original repo you forked from Added manually: git remote add upstream <url>

📋 Summary

  • A remote is a named URL pointing to another copy of the repository — stored in .git/config.
  • origin is the conventional name for the default remote, automatically set by git clone.
  • upstream is the convention for the original repo when you've forked.
  • git remote -v — list all remotes with URLs.
  • git remote add <name> <url> — add a new remote.
  • git remote rename and git remote remove — manage existing remotes.
  • Tracking branches (e.g., origin/main) are local snapshots of the remote branch's state at last fetch.

FAQ

Can a repository have multiple remotes? +

Yes — and it's common. The typical open-source setup has two: origin (your fork) and upstream (the original repo). Some teams push to multiple hosting services simultaneously (GitHub + an internal GitLab server). Each remote is independent — you can fetch from upstream and push to origin without any conflict.

What's the difference between a remote branch and a remote-tracking branch? +

A remote branch is a branch that lives on the remote server (e.g., main on GitHub). A remote-tracking branch is a local reference (e.g., origin/main) that mirrors what that remote branch looked like the last time you fetched. You can't commit directly to a remote-tracking branch — it's read-only and only updated by fetch/pull operations.

If I remove a remote, does it delete the repository on GitHub? +

No. git remote remove only removes the local reference (the name-URL entry in .git/config). The remote repository on GitHub is completely unaffected. You can re-add the remote at any time with git remote add. To actually delete a GitHub repository, you'd do that through the GitHub web interface.

Why does git remote -v show both "(fetch)" and "(push)" for the same URL? +

Git allows different URLs for fetch and push on the same remote — a rarely-used but valid configuration. For example, you might fetch over HTTPS (no credentials needed for public repos) but push over SSH. In most cases they're the same URL, so Git shows both to make the configuration transparent. You can set them separately with git remote set-url --push origin <url>.