Skip to main content
Multiple Remotes and Self-Hosting (Advanced)
This material was adapted from the OxfordRSE "Git and GitHub" course, a derivative work of the UCL Research Software Development Group teaching materials and the Software Carpentry "Version Control with Git" lesson.

This material was adapted from the OxfordRSE "Git and GitHub" course, a derivative work of the UCL Research Software Development Group teaching materials and the Software Carpentry "Version Control with Git" lesson.

Creative Commons License

Multiple Remotes and Self-Hosting (Advanced)

Advanced: safe to skip

This module covers working with several remotes and running your own Git server. Most users only ever need the single origin remote covered earlier, so feel free to skip this until you need it.

Centralised vs distributed

Older version control systems (like CVS and Subversion) were centralised: the history lived only on a server, and almost every operation required an internet connection.
Centralised (cvs, svn)Distributed (git, mercurial)
Server holds the historyA normal clone has the full history
Your computer has one snapshotMany local branches, offline
Need the network to view historyHistory always available locally
You commit to the remote serverUsers synchronise histories
Because Git is distributed, there is nothing special about origin - a clone is a complete repository in its own right, and you can connect to as many remotes as you like.

Working with a second remote

So far we have had a single remote called origin. But you might, for example, have your own fork of a project on GitHub as well as the original. You can add a second remote alongside origin:
git remote add upstream git@github.com:originalauthor/climate-analysis.git git remote -v
origin git@github.com:yourname/climate-analysis.git (fetch) origin git@github.com:yourname/climate-analysis.git (push) upstream git@github.com:originalauthor/climate-analysis.git (fetch) upstream git@github.com:originalauthor/climate-analysis.git (push)
Commands that talk to remotes let you name which one to use (they assume origin if you don't). So you can push a branch to your own fork while pulling updates from the original project:
git push origin main git pull upstream main

Referencing remotes

When you run git fetch, Git downloads the latest state of a remote without changing your working files, storing it under names like origin/main and upstream/main. On its own, git fetch only updates the remote you'd push to by default (usually origin) - to update every remote you've added, use git fetch --all. You can then compare against those references:
git fetch --all git log --oneline --left-right upstream/main...origin/main
To see which of your changes aren't yet on a particular remote:
git diff --name-only origin/main
And to see, for each local branch, which remote branch it tracks and whether it is ahead or behind:
git branch -vv
Remember that these references reflect the last time you fetched - run git fetch again to update them.

Hosting Git yourself

You don't need GitHub (or any hosting service) to have a remote. Any Git repository can act as a remote, as long as you can reach it over SSH or a shared filesystem. The trick is to use a bare repository - one with no working directory - because pushing into someone's checked-out working copy is dangerous.
Create a bare repository:
mkdir climate-analysis.git cd climate-analysis.git git init --bare
Then, from your normal working copy, add it as a remote and push:
git remote add local_bare ../climate-analysis.git git push -u local_bare main
You can now push to and pull from this repository like any other. If it lives on a machine you can SSH to, you can share it with collaborators:
# On the server ssh myserver mkdir climate-analysis.git cd climate-analysis.git git init --bare exit # On your machine git remote add myserver ssh://user@myserver/~/climate-analysis.git git push -u myserver main
This is a handy way to collaborate through a shared filesystem or a lab server when you don't want to (or can't) use a public hosting service.

Key Points

  • Git is distributed: every clone is a full repository, and you can connect to many remotes at once.
  • git remote add <name> <url> adds a second remote (e.g. upstream) alongside origin.
  • After git fetch, compare against references like origin/main and upstream/main; git branch -vv shows tracking status.
  • git init --bare creates a repository suitable for pushing to - host one yourself over SSH or a shared filesystem.