Say that you are following someone else’s project on github, and you want to submit a patch to their code. Unfortunately you don’t have access to their repository. Github recommends that you create a fork of their project — which is correct — but from there, their instructions are less helpful.
So, assuming that you’ve created a personal fork of their project, here is how you contribute your code.
First, checkout THEIR project and get into that directory:
$ git clone git://github.com/their/project.git
$ cd project
Now, add your fork as a remote repository, and give it the alias “bananas“:
$ git remote add bananas git://github.com/your/fork.git
Make any changes you need to make, “git add” and “git commit” as appropriate:
$ git add myfile.txt
$ git commit -m "i made changes"
Get the latest version of their code. (Note that you are putting your commits on top of their project’s master — not yours. This is correct, and allowed; you just won’t be able to push these changes to their repo.)
$ git pull --rebase
Since you can’t push to their repo, push the changes to YOUR repo (which you called “bananas“), in a new branch called “onions“:
$ git push bananas master:onions
The above command is taking their master branch with your commits on top of it and making a new branch in your personal fork. You could omit the “master:onions” bit, but then it would by default go into your “master” branch. In a perfect world, that would be fine… but in the real world, they might reject your changes (in which case, you have a lot of cleanup to do and even more so if you continued to commit and push). So make a new branch for every set of changes you want to submit. I tend to prefix my branches with the date (e.g. “2012-06-29_onions“).
Now that github has your changes, put their branch back the way that it was — keep everything all tidy:
$ git reset --hard origin/master
If you go to github now, you should see a new branch called “onions“– send a pull request based on this branch. From here, 1 of 3 things will happen:
- They accept your changes. You run “git pull --rebase” and get the now-official code that you contributed.
- They reject your changes. You start over from scratch at the add/commit step (since you reset your branch), and repeat the process.
- They reject your changes, but you want to keep building on those changes. You do “git checkout bananas/onions” to pull in the branch that you were working on. git pull --rebase origin/master to update it to the latest upstream code, then add/commit to it as appropriate. Then you can “git push bananas master:onions” again and update your pull request on github.
When you are all done with your branch, you can delete it by pushing a null branch to it:
$ git push bananas :onions