Skip to main content

Remotes โ€” Managing Remote Repositories

What is a Remote?โ€‹

A remote is a named reference to another Git repository โ€” typically hosted on GitHub, GitLab, Bitbucket, or an internal server. A remote stores a URL and a set of remote-tracking branches (origin/main, origin/develop) that are snapshots of the remote's branches as of the last fetch.

Most repositories have a single remote called origin (the repo you cloned from). Forks and multi-remote workflows add more.


Viewing Remotesโ€‹

# List remote names
git remote

# List remotes with their URLs
git remote -v
# origin [email protected]:your-org/transaction-service.git (fetch)
# origin [email protected]:your-org/transaction-service.git (push)

# Show detailed info about a specific remote
git remote show origin

Adding and Removing Remotesโ€‹

# Add a new remote
git remote add origin [email protected]:your-org/transaction-service.git
git remote add upstream [email protected]:original-org/transaction-service.git

# Remove a remote
git remote remove upstream

# Rename a remote
git remote rename origin github

Changing a Remote URLโ€‹

# Switch from HTTPS to SSH
git remote set-url origin [email protected]:your-org/transaction-service.git

# Switch from SSH to HTTPS
git remote set-url origin https://github.com/your-org/transaction-service.git

Fork Workflow (Upstream + Origin)โ€‹

When contributing to a project via a fork, you typically have two remotes:

# origin = your fork
# upstream = the original repository

git remote add upstream [email protected]:original-org/transaction-service.git
git remote -v
# origin [email protected]:your-username/transaction-service.git (fetch)
# origin [email protected]:your-username/transaction-service.git (push)
# upstream [email protected]:original-org/transaction-service.git (fetch)
# upstream [email protected]:original-org/transaction-service.git (push)

# Keep your fork's main in sync with upstream
git fetch upstream
git switch main
git merge upstream/main
git push origin main

Remote-Tracking Branchesโ€‹

Remote-tracking branches are read-only local snapshots of the remote's branches, updated on every git fetch. They follow the naming pattern <remote>/<branch>:

# View all remote-tracking branches
git branch -r
# origin/main
# origin/develop
# origin/feature/JIRA-123

# View local + remote
git branch -a

# Check how far behind/ahead you are
git log HEAD..origin/main --oneline # remote commits you don't have
git log origin/main..HEAD --oneline # your commits not yet on remote

Pruning Stale Remote-Tracking Refsโ€‹

After a remote branch is deleted, its remote-tracking ref lingers locally until pruned:

# Prune during fetch (recommended โ€” set globally)
git fetch --prune
git config --global fetch.prune true

# Prune without fetching
git remote prune origin

# See which refs would be pruned (dry run)
git remote prune origin --dry-run

Multiple Push Remotesโ€‹

Push to multiple remotes simultaneously (e.g., GitHub + internal GitLab mirror):

git remote set-url --add --push origin [email protected]:your-org/repo.git
git remote set-url --add --push origin [email protected]:your-org/repo.git

git push origin main # pushes to both URLs

Useful Flags Summaryโ€‹

CommandMeaning
git remote -vList remotes with URLs
git remote add <name> <url>Add a new remote
git remote remove <name>Remove a remote
git remote rename <old> <new>Rename a remote
git remote set-url <name> <url>Change a remote's URL
git remote show <name>Inspect a remote's branches and tracking status
git remote prune <name>Remove stale remote-tracking refs
git fetch --pruneFetch and prune in one step

Use SSH Over HTTPS

SSH authentication (via key pair) is more convenient than HTTPS for daily use โ€” no password prompts, and access tokens don't expire. Set up an SSH key once and all Git operations are frictionless:

ssh-keygen -t ed25519 -C "[email protected]"
cat ~/.ssh/id_ed25519.pub # add this to GitHub/GitLab SSH settings

Interview Questions (Senior Level)โ€‹

  1. How do you design remote strategy for fork-based OSS contribution plus internal mirror compliance?
  2. What controls prevent pushing sensitive commits to the wrong remote in multi-remote setups?
  3. How do you manage upstream synchronization at scale to reduce divergence and conflict cost?
  4. When should teams enforce fetch.prune=true, and what pitfalls should be communicated?

Short answer guide:

  • Separate origin/upstream roles and automate sync routines.
  • Use protected remotes, pre-push hooks, and scoped credentials.
  • Regular rebase/merge cadence plus automation avoids drift.
  • Pruning keeps refs clean but requires awareness of deleted branch recovery paths.