Git workflow: Forks, remotes, and pull requests

I've been asked a number of times about what I consider to be a nice, clean way of dealing with Git/GitHub hosted projects with multiple developers so I figured I should just publish somethere here so I can point people to it and just say, 'that'. So here we go.

To start with, each developer should have their own fork of the 'main' project repository. For example there might be a company/the-project.git repo that I would fork into nathanhoad/the-project.git (just so you know, private organisation repos are still private when forked).

Now clone your fork. As always, this fork will have the 'origin' remote already set up but we also want to add an upstream Git remote to point to the main project fork. So grab the Git URL for the main project and do something like this:

git remote add upstream [email protected]:company/the-project.git

Don't worry too much about this upstream remote just yet, we'll come back to that soon.

Working on a feature

Whenever you're working on a new feature you should create a branch for it. So, let's say you are working on 'some new feature' and create a branch called 'some-new-feature' (git checkout -b some-new-feature). Do your stuff, commit the changes, and then push them to your fork (origin):

git push origin some-new-feature

Then have a look on GitHub and create a Pull Request (there will be a big button asking if you want your last push to be made into a Pull Request, which you do).

After the Pull Request has been accepted and merged into the main project repo you can pull it from upstream and merge it back into your fork (and delete your feature branch because it's not needed any more):

git checkout master
git pull upstream master
git branch -d some-new-feature

This process is then repeated for the next feature, and the one after that, and after that... you get the idea.

Working with another developers fork

If you need to work with another developer on a feature and they have a branch in their own fork that you want to pull from then you can add their fork as a remote:

git remote add john [email protected]:john/the-project.git

Now you can pull from their branch into your own:

git checkout some-other-feature
git pull john some-other-feature

The branch names don't have to be the same but it certainly makes it easier to follow if they are.

It might all sound a bit complicated at first but after following the process a few times you'll wonder how anybody manages projects any other way. If you have any questions, hit me up on Twitter.