German German - 2 months ago 17
Git Question

What's the workflow to contribute to an open source project using git pull requests? (eg. via Github)

I have a comprehensive step by step description on how I do this and I wanted to share it here so developers can benefit from it (I'll answer my own question).

Answer

Since changes contributed to open source projects will have to be peer reviewed it's common to see a workflow which relies on git pull requests. Pull requests are not allowed from directly cloned repos (you need your own fork). So these are the steps I follow to maintain a healthy fork and contribute to an open source periodically:

Note: Steps 1, 2 and 3 are only done once on a single development machine to set everything up:

1) Make sure you're working locally on your "fork" of the project rather than on a cloned repository pointing to the project as origin. In order to fork a Github project go to https://github.com/entity/project , click on "Fork" and choose a suitable GitHub account for the fork eg. your personal Github account. Note that your forked project "origin" will be no longer the original project repo but your own fork on Github. Be careful with privacy if you're forking a private project since you probably don't want your fork to be public.

2) Clone your own project fork into your development machine.

git clone git@github.com:yourgithubuser/project.git

3) Add the original project repo as upstream repository in your forked project.

git remote add upstream git@github.com:entity/project.git

The original main project repo is now "upstream" but not "origin"

And now comes the work loop that you'll repeat when you work with your forked project:

4) Before starting your work always make sure the master branch of your forked repo is synchronized with the master branch of the original project repo:

git checkout master
git fetch upstream
git merge upstream/master
git push origin master

5) Create a new branch in your project fork for the specific fixes that you want to contribute (name it after either a bugfix, a tracker issue, a documentation section, etc) and switch to it.

git checkout -b myfixes

This automatically creates the branch and switches to it. Make sure the branch does not exist already. You might also want to get rid of your old fix branches that have already been merged into the docs (otherwise you'll have tons of useless branches in your project):

git branch -D myoldfixes
git push origin --delete myoldfixes

Important note: if you were already working on a branch on a different machine and want to continue that work on a new machine you need to redo steps 2, 3 and 4 on the new machine and in step 5 instead of doing git checkout -b myfixes you should do git checkout myfixes (remove the -b). Otherwise you can end up with a "detached head" state which is not good (kind of an anonymous branch)

6) Work on that branch (eg. myfixes) and commit your changes:

git commit -a -m "My fixes"

(Alternatively you can stage specific files and commit without using -a. You can commit as many times as you want but don't leave uncommited changes in the branch)

7) While you were working on your fixes the original upstream project repo might have changed (due to other contributors working on it). So first you'll have to rebase your current branch (myfixes) from the upstream destination branch. In other words you need to replay your fixes on top of that latest work from upstream repo master branch to make sure your commits are still compatible with the latest commits in upstream. This will result in a fast-forward merge for the pull request which is what we want:

git checkout myfixes
git pull --rebase upstream master

Note: this can result in conflicts but this is normal, fixing them is part of the process (this happens more often on very active projects)

8) After fixing the conflicts (if any) of the previous step you have applied your fixes on top of the latest version of upstream master. Since the pull requests are initiated from your forked repository on Github you want to keep that one in sync too:

git checkout myfixes
git push origin myfixes

9) Finally, you can go to Github https://github.com/yourgithubuser/project and click on "Pull Request". Make sure you choose upstream repo "master" as the destination branch and your forked repo "myfixes" as the source branch (the branch will be automatically removed for you after the pull request is accepted)

Enjoy!

Comments