[git] How do I update a GitHub forked repository?

I recently forked a project and applied several fixes. I then created a pull request which was then accepted.

A few days later another change was made by another contributor. So my fork doesn't contain that change.

How can I get that change into my fork? Do I need to delete and re-create my fork when I have further changes to contribute? Or is there an update button?

This question is related to git github updates pull-request git-fork

The answer is


rm -rf oldrepository
git clone ...

There may be subtler options, but it is the only way that I have any confidence that my local repository is the same as upstream.


That depends on the size of your repository and how you forked it.

If it's quite a big repository you may have wanted to manage it in a special way (e.g. drop history). Basically, you can get differences between current and upstream versions, commit them and then cherry pick back to master.

Try reading this one. It describes how to handle big Git repositories and how to upstream them with latest changes.


Assuming your fork is https://github.com/me/foobar and original repository is https://github.com/someone/foobar

  1. Visit https://github.com/me/foobar/compare/master...someone:master

  2. If you see green text Able to merge then press Create pull request

  3. On the next page, scroll to the bottom of the page and click Merge pull request and Confirm merge.


There are two main things on keeping a forked repository always update for good.

1. Create the branches from the fork master and do changes there.

So when your Pull Request is accepted then you can safely delete the branch as your contributed code will be then live in your master of your forked repository when you update it with the upstream. By this your master will always be in clean condition to create a new branch to do another change.

2. Create a scheduled job for the fork master to do update automatically.

This can be done with cron. Here is for an example code if you do it in linux.

$ crontab -e

put this code on the crontab file to execute the job in hourly basis.

0 * * * * sh ~/cron.sh

then create the cron.sh script file and a git interaction with ssh-agent and/or expect as below

#!/bin/sh
WORKDIR=/path/to/your/dir   
REPOSITORY=<name of your repo>
MASTER="[email protected]:<username>/$REPOSITORY.git"   
[email protected]:<upstream>/<name of the repo>.git  

cd $WORKDIR && rm -rf $REPOSITORY
eval `ssh-agent` && expect ~/.ssh/agent && ssh-add -l
git clone $MASTER && cd $REPOSITORY && git checkout master
git remote add upstream $UPSTREAM && git fetch --prune upstream
if [ `git rev-list HEAD...upstream/master --count` -eq 0 ]
then
    echo "all the same, do nothing"
else
    echo "update exist, do rebase!"
    git reset --hard upstream/master
    git push origin master --force
fi
cd $WORKDIR && rm -rf $REPOSITORY
eval `ssh-agent -k`

Check your forked repository. From time to time it will always show this notification:

This branch is even with <upstream>:master.

enter image description here


If, like me, you never commit anything directly to master, which you should really, you can do the following.

From the local clone of your fork, create your upstream remote. You only need to do that once:

git remote add upstream https://github.com/whoever/whatever.git

Then whenever you want to catch up with the upstream repository master branch you need to:

git checkout master
git pull upstream master

Assuming you never committed anything on master yourself you should be done already. Now you can push your local master to your origin remote GitHub fork. You could also rebase your development branch on your now up-to-date local master.

Past the initial upstream setup and master checkout, all you need to do is run the following command to sync your master with upstream: git pull upstream master.


If you are using GitHub for Windows or Mac then now they have a one-click feature to update forks:

  1. Select the repository in the UI.
  2. Click "Update from user/branch" button the top.

When you have cloned your forked repository, go to the directory path where your clone resides and the few lines in your Git Bash Terminal.

$ cd project-name

$ git remote add upstream https://github.com/user-name/project-name.git
 # Adding the upstream -> the main repo with which you wanna sync

$ git remote -v # you will see the upstream here 

$ git checkout master # see if you are already on master branch

$ git fetch upstream

And there you are good to go. All updated changes in the main repository will be pushed into your fork repository.

The "fetch" command is indispensable for staying up-to-date in a project: only when performing a "git fetch" will you be informed about the changes your colleagues pushed to the remote server.

You can still visit here for further queries


Foreword: Your fork is the "origin" and the repository you forked from is the "upstream".

Let's assume that you cloned already your fork to your computer with a command like this:

git clone [email protected]:your_name/project_name.git
cd project_name

If that is given then you need to continue in this order:

  1. Add the "upstream" to your cloned repository ("origin"):

    git remote add upstream [email protected]:original_author/project_name.git
    
  2. Fetch the commits (and branches) from the "upstream":

    git fetch upstream
    
  3. Switch to the "master" branch of your fork ("origin"):

    git checkout master
    
  4. Stash the changes of your "master" branch:

    git stash
    
  5. Merge the changes from the "master" branch of the "upstream" into your the "master" branch of your "origin":

    git merge upstream/master
    
  6. Resolve merge conflicts if any and commit your merge

    git commit -am "Merged from upstream"
    
  7. Push the changes to your fork

    git push
    
  8. Get back your stashed changes (if any)

    git stash pop
    
  9. You're done! Congratulations!

GitHub also provides instructions for this topic: Syncing a fork


I update my forked repos with this one line:

git pull https://github.com/forkuser/forkedrepo.git branch

Use this if you dont want to add another remote endpoint to your project, as other solutions posted here.


I would like to add on to @krlmlr's answer.

Initially, the forked repository has one branch named : master. If you are working on a new feature or a fix, you would generally create a new branch feature and make the changes.

If you want the forked repository to be in sync with the parent repository, you could set up a config file(pull.yml) for the Pull app (in the feature branch), like this:

version: "1"
rules:
  - base: feature
    upstream: master
    mergeMethod: merge
  - base: master
    upstream: parent_repo:master
    mergeMethod: hardreset

This keeps the master branch of the forked repo up-to-date with the parent repo. It keeps the feature branch of the forked repo updated via the master branch of the forked repo by merging the same. This assumes that the feature branch is the default branch which contains the config file.

Here two mergemethods are into play, one is hardreset which helps force sync changes in the master branch of the forked repo with the parent repo and the other method is merge. This method is used to merge changes done by you in the feature branch and changes done due to force sync in the master branch. In case of merge conflict, the pull app will allow you to choose the next course of action during the pull request.

You can read about basic and advanced configs and various mergemethods here.

I am currently using this configuration in my forked repo here to make sure an enhancement requested here stays updated.


Actually, it is possible to create a branch in your fork from any commit of the upstream in the browser:

Enter image description here

You can then fetch that branch to your local clone, and you won't have to push all that data back to GitHub when you push edits on top of that commit. Or use the web interface to change something in that branch.

How it works (it is a guess, I don't know how exactly GitHub does it): forks share object storage and use namespaces to separate users' references. So you can access all commits through your fork, even if they did not exist by the time of forking.


If you want to keep your GitHub forks up to date with the respective upstreams, there also exists this probot program for GitHub specifically: https://probot.github.io/apps/pull/ which does the job. You would need to allow installation in your account and it will keep your forks up to date.


As a complement to this answer, I was looking for a way to update all remote branches of my cloned repo (origin) from upstream branches in one go. This is how I did it.

This assumes you have already configured an upstream remote pointing at the source repository (where origin was forked from) and have synced it with git fetch upstream.

Then run:

for branch in $(git ls-remote --heads upstream|sed 's#^.*refs/heads/##'); do git push origin refs/remotes/upstream/$branch:refs/heads/$branch; done

The first part of this command lists all heads in the upstream remote repo and removes the SHA-1 followed by refs/heads/ branch name prefix.

Then for each of these branches, it pushes the local copy of the upstream remote tracking branch (refs/remotes/upstream/<branch> on local side) directly to the remote branch on origin (refs/heads/<branch> on remote side).

Any of these branch sync commands may fail for one of two reasons: either the upstream branch have been rewritten, or you have pushed commits on that branch to your fork. In the first case where you haven't committed anything to the branch on your fork it is safe to push forcefully (Add the -f switch; i.e. git push -f in the command above). In the other case this is normal as your fork branch have diverged and you can't expect the sync command to work until your commits have been merged back into upstream.


How to update your forked repo on your local machine?

First, check your remote/master

git remote -v

You should have origin and upstream. For example:

origin  https://github.com/your___name/kredis.git (fetch)
origin  https://github.com/your___name/kredis.git (push)
upstream    https://github.com/rails/kredis.git (fetch)
upstream    https://github.com/rails/kredis.git (push)

After that go to main:

git checkout main

and merge from upstream to main:

git merge upstream/main

There's a way to do it from GitHub's webapp.

Let's go through the following example.

To start with, open the repo that you want to update.

enter image description here

One can see the warning

This branch is 157 commits behind GoogleCloudPlatform:master.

On the right there are two buttons Pull request and Compare. Press Compare.

As there is probably nothing to compare, press switching the base

enter image description here

A list of all the changes will appear and one can create a pull request by pressing the button Create pull request

enter image description here

Give it a title, let's say "Update repo"

enter image description here

And create the pull request.

Once the request is created, scroll to the bottom and press Merge pull request.

enter image description here

Confirm the merge and that's it!


Android Studio now has learned to work with GitHub fork repositories (you don't even have to add "upstream" remote repository by console command).

Open menu VCS ? Git

And pay attention to the two last popup menu items:

  • Rebase my GitHub fork

  • Create Pull Request

Try them. I use the first one to synchronize my local repository. Anyway the branches from the parent remote repository ("upstream") will be accessible in Android Studio after you click "Rebase my GitHub fork", and you will be able to operate with them easily.

(I use Android Studio 3.0 with "Git integration" and "GitHub" plugins.)

Enter image description here


If you set your upstream. Check with git remote -v, then this will suffice.

git fetch upstream
git checkout master
git merge --no-edit upstream/master
git push

Here is GitHub's official document on Syncing a fork:

Syncing a fork

The Setup

Before you can sync, you need to add a remote that points to the upstream repository. You may have done this when you originally forked.

Tip: Syncing your fork only updates your local copy of the repository; it does not update your repository on GitHub.

$ git remote -v
# List the current remotes
origin  https://github.com/user/repo.git (fetch)
origin  https://github.com/user/repo.git (push)

$ git remote add upstream https://github.com/otheruser/repo.git
# Set a new remote

$ git remote -v
# Verify new remote
origin    https://github.com/user/repo.git (fetch)
origin    https://github.com/user/repo.git (push)
upstream  https://github.com/otheruser/repo.git (fetch)
upstream  https://github.com/otheruser/repo.git (push)

Syncing

There are two steps required to sync your repository with the upstream: first you must fetch from the remote, then you must merge the desired branch into your local branch.

Fetching

Fetching from the remote repository will bring in its branches and their respective commits. These are stored in your local repository under special branches.

$ git fetch upstream
# Grab the upstream remote's branches
remote: Counting objects: 75, done.
remote: Compressing objects: 100% (53/53), done.
remote: Total 62 (delta 27), reused 44 (delta 9)
Unpacking objects: 100% (62/62), done.
From https://github.com/otheruser/repo
 * [new branch]      master     -> upstream/master

We now have the upstream's master branch stored in a local branch, upstream/master

$ git branch -va
# List all local and remote-tracking branches
* master                  a422352 My local commit
  remotes/origin/HEAD     -> origin/master
  remotes/origin/master   a422352 My local commit
  remotes/upstream/master 5fdff0f Some upstream commit

Merging

Now that we have fetched the upstream repository, we want to merge its changes into our local branch. This will bring that branch into sync with the upstream, without losing our local changes.

$ git checkout master
# Check out our local master branch
Switched to branch 'master'

$ git merge upstream/master
# Merge upstream's master into our own
Updating a422352..5fdff0f
Fast-forward
 README                    |    9 -------
 README.md                 |    7 ++++++
 2 files changed, 7 insertions(+), 9 deletions(-)
 delete mode 100644 README
 create mode 100644 README.md

If your local branch didn't have any unique commits, git will instead perform a "fast-forward":

$ git merge upstream/master
Updating 34e91da..16c56ad
Fast-forward
 README.md                 |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

Tip: If you want to update your repository on GitHub, follow the instructions here


If you use GitHub Desktop, you can do it easily in just 6 steps (actually only 5).

Once you open Github Desktop and choose your repository,

  1. Go to History tab
  2. Click on the search bar. It will show you all the available branches (including upstream branches from parent repository)
  3. Select the respective upstream branch (it will be upstream/master to sync master branch)
  4. (OPTIONAL) It will show you all the commits in the upstream branch. You can click on any commit to see the changes.
  5. Click Merge in master / branch-name, based on your active branch.
  6. Wait for GitHub Desktop to do the magic.

Checkout the GIF below as an example:

Sync Upstream branches in a forked repository from the parent repository


The "Pull" app is an automatic set-up-and-forget solution. It will sync the default branch of your fork with the upstream repository.

Visit the URL, click the green "Install" button and select the repositories where you want to enable automatic synchronization.

The branch is updated once per hour directly on GitHub, on your local machine you need to pull the master branch to ensure that your local copy is in sync.


Starting in May 2014, it is possible to update a fork directly from GitHub. This still works as of September 2017, BUT it will lead to a dirty commit history.

  1. Open your fork on GitHub.
  2. Click on Pull Requests.
  3. Click on New Pull Request. By default, GitHub will compare the original with your fork, and there shouldn't be anything to compare if you didn't make any changes.
  4. Click switching the base if you see that link. Otherwise, manually set the base fork drop down to your fork, and the head fork to the upstream. Now GitHub will compare your fork with the original, and you should see all the latest changes. enter image description here
  5. Create pull request and assign a predictable name to your pull request (e.g., Update from original).
  6. Scroll down to Merge pull request, but don't click anything yet.

Now you have three options, but each will lead to a less-than-clean commit history.

  1. The default will create an ugly merge commit.
  2. If you click the dropdown and choose "Squash and merge", all intervening commits will be squashed into one. This is most often something you don't want.
  3. If you click Rebase and merge, all commits will be made "with" you, the original PRs will link to your PR, and GitHub will display This branch is X commits ahead, Y commits behind <original fork>.

So yes, you can keep your repo updated with its upstream using the GitHub web UI, but doing so will sully your commit history. Stick to the command line instead - it's easy.


A lot of answers end up moving your fork one commit ahead of the parent repository. This answer summarizes the steps found here which will move your fork to the same commit as the parent.

  1. Change directory to your local repository.

    • Switch to master branch if you are not git checkout master
  2. Add the parent as a remote repository, git remote add upstream <repo-location>

  3. Issue git fetch upstream
  4. Issue git rebase upstream/master

    • At this stage you check that commits what will be merged by typing git status
  5. Issue git push origin master

For more information about these commands, refer to step 3.


Since November 2013 there has been an unofficial feature request open with GitHub to ask them to add a very simple and intuitive method to keep a local fork in sync with upstream:

https://github.com/isaacs/github/issues/121

Note: Since the feature request is unofficial it is also advisable to contact [email protected] to add your support for a feature like this to be implemented. The unofficial feature request above could be used as evidence of the amount of interest in this being implemented.


Delete your remote dev from github page

then apply these commands:

1) git branch -D dev
2) git fetch upstream
3) git checkout master
4) git fetch upstream && git fetch upstream --prune && git rebase upstream/master && git push -f origin master
5) git checkout -b dev
6) git push origin dev
7) git fetch upstream && git fetch upstream --prune && git rebase upstream/dev && 8) git push -f origin dev

Follow the below steps. I tried them and it helped me.

Checkout to your branch

Syntax: git branch yourDevelopmentBranch
Example: git checkout master

Pull source repository branch for getting the latest code

Syntax: git pull https://github.com/tastejs/awesome-app-ideas master
Example: git pull https://github.com/ORIGINAL_OWNER/ORIGINAL_REPO.git BRANCH_NAME


Use these commands (in lucky case)

git remote -v
git pull
git fetch upstream
git checkout master
git merge upstream/master --no-ff
git add .
git commit -m"Sync with upstream repository."
git push -v

As of the date of this answer, GitHub has not (or shall I say no longer?) this feature in the web interface. You can, however, ask [email protected] to add your vote for that.

In the meantime, GitHub user bardiharborow has created a tool to do just this: https://upriver.github.io/

Source is here: https://github.com/upriver/upriver.github.io


Examples related to git

Does the target directory for a git clone have to match the repo name? Git fatal: protocol 'https' is not supported Git is not working after macOS Update (xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools) git clone: Authentication failed for <URL> destination path already exists and is not an empty directory SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 GitLab remote: HTTP Basic: Access denied and fatal Authentication How can I switch to another branch in git? VS 2017 Git Local Commit DB.lock error on every commit How to remove an unpushed outgoing commit in Visual Studio?

Examples related to github

Does the target directory for a git clone have to match the repo name? Issue in installing php7.2-mcrypt How can I switch to another branch in git? How to draw checkbox or tick mark in GitHub Markdown table? How to add a new project to Github using VS Code git clone error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054 How to add empty spaces into MD markdown readme on GitHub? key_load_public: invalid format git - remote add origin vs remote set-url origin Cloning specific branch

Examples related to updates

Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes Update a dataframe in pandas while iterating row by row How does it work - requestLocationUpdates() + LocationRequest/Listener Run local java applet in browser (chrome/firefox) "Your security settings have blocked a local application from running" How do I update a GitHub forked repository? How to know when a web page was last updated?

Examples related to pull-request

How to remove commits from a pull request How can I check out a GitHub pull request with git? Delete a closed pull request from GitHub How to do a GitHub pull request How do I update a GitHub forked repository? Undo a merge by pull request? How to cancel a pull request on github? Can you issue pull requests from the command line on GitHub?

Examples related to git-fork

error: pathspec 'test-branch' did not match any file(s) known to git Copy a git repo without history How to do a GitHub pull request How do I update a GitHub forked repository? Are Git forks actually Git clones?