Can I merge the commits made to a fork back to the original project?

Viewed 1215

Despite programming for a few years now, I'm still trying to wrap my head around some concepts when it comes to Git. To illustrate what I'm asking, let's set the stage with a hypothetical situation:

  • I create a open-source clone of Flappy Bird for whatever reason and make the code available on GitHub under a MIT license
  • Someone finds my chicken-scratch code and decides to fork the project (note: not fork for pull request) then proceeds to make well-meaning improvements

With the Git system, is it possible to merge commits from forks upstream?

3 Answers

To add to hellyale's comment, if you see a fork whose (for instance) master branch has some changes you want to test / get into your own original repository ("upstream" compared to that fork), you don't have to wait for a pull request.

You can, in a local clone of your own repository, do:

git remote add fork https://url/fork
git fetch fork
git merge fork/master
# test, and if good
git push

Although not often used that way, git is a fully decentralised system: it doesn't treat any repository as "more central" or "more official" than any other. Concepts such as "fork" and "upstream" are just conventions, as far as git is concerned there's not even a difference between Github and the copy on your local PC.

So the simple answer is that if you have read access to repository A, and write access to repository B, you can always copy commits from A to B.

In your example, you have write access to the "upstream" repository (because you created it) and read access to someone else's fork (because they've published it somewhere). The most general method is something like this:

  • Clone the repository locally (so now we have three repositories!)
  • Add "remotes" for both A and B (which is git jargon for associating the URL you can access a repository on with a local name; when you clone, a remote called "origin" is added for you)
  • Fetch the branches you want to merge from these remotes
  • Check out those branches, merge them into each other or into some new branch, all in the same way as if only your local repo existed
  • Push the result up to B (copying up all the relevant commits that didn't already exist there, and updating the remote server's record of where the branch points)

If both A and B are on the same hosting service (Github, Gitlab, BitBucket, etc) you can probably use that service to create the merge directly, but it's useful to remember that that's just a convenient tool they provide, and git won't treat it any differently from any other merge.

There are a couple ways to go about this (providing I interpreted your question correctly):

  1. Providing the other person's forked version of your repository is public, you can create a pull request from the GitHub UI from their repo back into yours. You would want to create a pull request from their branch containing the desired changes, then open the PR into the master branch of your repo.

This integrates their changes into the master branch of your version of the repo. This is generally an anti-pattern, but it might make sense in this case if you don't wish to use the command-line...

  1. As hellyvale mentioned above, you can use the command-line:
cd <directory_containing_local_clone_of_your_repo>
git checkout master
git remote add fork git@github.com:user_who_forked/forked_repo_name.git # adds forked repo as a remote called "fork" 
git remote -v # verify the user's fork is listed
git fetch fork
git merge fork/master # make sure you're on your master branch first
git push # assuming your remote is the default remote, otherwise you can call it by name

You might have to sort out some merge conflicts if the changes you're trying to merge conflict with your code and Git is unable to automatically resolve differences. This would have to be cleared up via an interactive rebase or manually selecting which commits to change. If this occurs, I'd recommend taking a look at the documentation for git-rebase.

Related