Syncing a Fork of a GitHub Repository with Upstream

Date Published: 07 June 2019

Syncing a Fork of a GitHub Repository with Upstream

Update 13 October 2023

GitHub made this easier. You can still use the approach below, but also check out how you can Fetch Upstream directly in GitHub.com.

I work on a few GitHub projects, like the Microsoft Docs, where I'm a relatively frequent contributor but I don't have commit rights. This means that I need to make a fork of their repository, do some work in my fork, and then send a pull request from my forked repository to the original one. This is actually a pretty common way of working in open source software, and doing it once is pretty straightforward.

However, GitHub only lets you fork a repository once. And it doesn't offer any way to update that fork from the web interface. So, once you've got a fork, you have a snapshot-in-time of the original repository, but if a few months later you want to make more additions, you'd better update your fork to the latest version of its upstream repository before you start working on your additions.

For this example I'm going to use the Microsoft .NET Docs GitHub repo as the upstream repo and my own fork of the docs repo as the fork I'm trying to sync.

The first thing you need to do is make sure you have a git remote configured for the upstream (original, source) repository. You can view your current remotes with this command:

$ git remote
origin

To add the repository from which you forked and name it upstream, you would use the git remote add command like so:

$ git remote add upstream https://github.com/dotnet/docs.git

You can confirm it worked by running git remote again:

$ git remote
origin
upstream

Now you need to sync your local git repo with the upstream version. There are 3 git repositories involved here: upstream, origin, local. You're going to apply changes from upstream to local first, and then push them to origin after that's done. To get the changes from the upstream repo, you need to fetch them (and specify the remote).

$ git fetch upstream

Now check out your main`` branch and merge the upstream main` into it:

$ git checkout main
Switched to branch 'main'

$ git merge upstream/main
Updating  `a422352..5fdff0f`
...

At this point your local repo is up to date with the upstream repo. The last step is to push your changes up to your fork on GitHub.

$ git push

And you're done! Now you're all set to work on your 2nd (or Nth) pull request for the upstream repository using the same fork you created some time ago.

Reset to Upstream

What if things are out of whack and you just want to reset your branch to the upstream version, losing anything that may be committed to your fork that you don't intend to pull request upstream? Follow these steps, originally described here:

# ensures current branch is main
git checkout main

# pulls all new commits made to upstream/main
git pull upstream main

# this will delete all your local changes to main
git reset --hard upstream/main

# take care, this will delete all your changes on your forked main
git push origin main --force

If you found this helpful, consider retweeting this tweet so others can easily find this article as well:

Additional References

Steve Smith

About Ardalis

Software Architect

Steve is an experienced software architect and trainer, focusing on code quality and Domain-Driven Design with .NET.