How to sync your GitHub fork with its upstream repository

A forked repository on GitHub is a copy of an upstream repository at a specific point in time. Git does not keep your forked repository in sync automatically, since the upstream repository continues to receive commits while your fork remains unchanged.

In this article, I show you how to sync your forked repository with the upstream repository in the following steps.

0. Fork the upstream repository

Forking is not a Git command, it happens on GitHub. You either click on the Fork button on the page of the upstream repository and then clone your forked repository, or do both in one go with the GitHub CLI:

gh repo fork <upstream-owner>/<repo> --clone

If you used the gh command, the upstream remote from step 1 is already set up for you, so you can skip straight to step 2.

1. Add the upstream remote

When you clone your forked repository, Git gives you exactly one remote, origin, pointing at it. The upstream repository is not registered at all, so we can add it using the conventional name upstream. This is a one-time step per local repository:

git remote add upstream <upstream-url>

Check that both remotes are registered to your local repository:

git remote -v

Which will give you something like:

origin    https://github.com/<you>/<repo>.git (fetch)
origin    https://github.com/<you>/<repo>.git (push)
upstream  https://github.com/<upstream-owner>/<repo>.git (fetch)
upstream  https://github.com/<upstream-owner>/<repo>.git (push)

2. Fetch the new commits from the upstream repository

git fetch upstream

This downloads the new commits from the upstream repository into your local repository. It does not change your current branch or your files.

3. Merge the changes of the upstream repository into your main branch

git switch main
git merge --no-edit upstream/main

This brings all the changes of the upstream repository into your local main. If your main has no commits of its own, Git simply moves it forward. If it has, Git adds a merge commit that joins the two histories. The --no-edit flag accepts Git’s default message for that merge commit and it will not open an editor.

4. Push to your forked repository

git push origin main

This publishes the updated main back to your forked repository.

How to work with a forked repository

  1. Keep the main of your forked repository as a mirror of the upstream repository and never commit to it directly.

  2. Every time you have a change in your forked repository, sync main with steps 2 to 4 above and then create a new branch from it for your work:

    git switch main
    git fetch upstream
    git merge --ff-only upstream/main
    git push origin main
    
    git switch -c feature/my-change
    

    If you committed to main by mistake, --ff-only stops with an error instead of creating a merge commit.

  3. Your changes do not get merged into your own main. They reach it through the upstream repository:

    • Push the feature branch to your forked repository with git push origin feature/my-change.
    • On GitHub, open a pull request from that branch into the main of the upstream repository.
    • Once the maintainer merges it, your next sync brings the change into the main of your forked repository.

Feel free to drop me a comment, if you found this article helpful.

comments powered by Disqus