Working with Forks on GitHub or CodePlex

So you want to contribute to a Git project on GitHub or CodePlex. The first thing you always do here is create a fork, which is easy enough:

image

image

After you create your fork, you’ll likely then clone that forked repository locally like:

git clone git@github.com:jbogard/AutoMapper.git

That’ll create a remote called “origin” that points up to your fork (in this case, on github). Check out the Git book for more info on remotes.

But we’re not quite done. We’ve created a fork, which is its own entire repository, separate from the original “central” repository:

image

In this new distributed reality, we need to be able to work with those upstream repositories effectively.

Making changes

If you want to make changes locally, great! But always make those changes in a branch. What we want to do is still be able to pull in any upstream changes, but isolate any contributions we make to the project. In order to do so, we’ll always create a local AND remote branch for any work we do. Our workflow looks like this:

git checkout -b MyFeature
**work work work & commit changes locally**
git push origin MyFeature

The reason we want to isolate our custom work from the master branch is that it makes it much, much easier to integrate and keep up to date with upstream changes. An example in GitHub is:

image

I have two branches – the default “master” branch, and one that I’m going to isolate for a pull request. The nice thing about CodePlex and GitHub is that they both allow you to “add” changes in the form of commits to your pull request. By isolating potential pull requests into a separate, dedicated remote branch, we can ensure that we don’t paint ourselves into a corner where we want to pull in upstream changes or work on something else.

Branches – local and remote – isolate work, and both GitHub and CodePlex work well with branches as pull requests.

When you’re done with any upstream changes, and our pull request is either accepted or rejected – kill your local and remote branch:

git branch -D MyFeature
git push origin :MyFeature

Once our changes are integrated (if they are), we want to use the upstream repository’s version of our changes.

Pulling upstream changes

When you create a fork, you’ll also want a way to keep up to date with the upstream repository. The first thing to do will be to add a remote that points to the upstream repository (conventionally named “upstream”):

git remote add upstream git://github.com/AutoMapper/AutoMapper.git

With that remote added, we want to fetch upstream, merge all local branches with that repository, and push that to our upstream:

git checkout master
git fetch upstream
git merge upstream/master (for each upstream branch)
git push origin

This workflow:

  1. Fetches all upstream commits
  2. Merges our local branches (as fast-forward merges) to the upstream’s repository’s versions
  3. Synchronizes our fork with upstream changes by pushing our local repository up.

It’s a little weird that we have to work with our local repository to synchronize our fork with the upstream repository, but that’s just because it would be a little hard to try and do that directly in GitHub.

The *first* thing you should do after forking a project and cloning that fork locally is add that “upstream” remote. It’s just much, much easier to have it set up early and get into the flow of fetch, merge, push for incorporating upstream changes.

To review, working with forks on GitHub and CodePlex is easy if we do two things:

  • Create an “upstream” remote to represent the repository our fork originated from
  • Always work in named local and remote branches for any commits we do in our fork

For more info, check out GitHub’s help pages.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in git. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Matt Enright

    I always find it best to, immediately after cloning, delete all of the “mirror branches” from the upstream repo. You’re almost always going to continue updating from upstream anyways, and it’s just as easy to work with ‘upstream/master’ as it is ‘origin/master’, without the mental burden of having to a) keep your fork versions up-to-date, for no real reason, and b) double the amount of references (which clutter up things like log –all or branch –contains).

    GitHub won’t let you delete ‘master’, since it has to have one checked
    out for display, but you can either let that sit fallow, or if you’re
    going to be more heavily dev’ing on the fork, switch the active branch
    to your own personal ‘next’ or something as taste dictates (and then
    delete the master).

    Just a maybe-helpful addition. Thanks for writing this!

  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1078