Keeping a clean GitHub fork - Part 1

Posted by Evan on December 3, 2011 General Add comments Tagged with: ,
Dec 032011

Let’s face it, nobody likes a dirty fork. In this series, I’ll show you some of the tricks I’ve learned over the years to successfully maintain a clean fork on GitHub for projects I actively contribute to.

The examples here will be catered towards people wanting to contribute to the Zend Framework project on GitHub, however the advice given not actually specific to Zend Framework. My advice may also differ slightly from that mentioned in the Zend Framework Git Guide, as it incorporates practices I have acquired over my years of using Git and working on open source projects.

Initial set-up

First, we’ll assume you’ve forked the ZF2 repository into your personal GitHub account and cloned from your own private SSH clone URL:

[user@workstation workspace]$ git clone git@github.com:EvanDotPro/zf2.git
[user@workstation workspace]$ cd ./zf2

You’ll want to add a remote called upstream pointing to the canonical repository. This will allow you to easily keep your local master up-to-date (covered below).

[user@workstation zf2 (master)]$ git remote add upstream git://github.com/zendframework/zf2.git

You may want to also add some other remotes of developers you follow or collaborate with so that you have easy access to all their most recent work. As a personal preference, I tend to match the remote name to their username on GitHub. For example:

[user@workstation zf2 (master)]$ git remote add weierophinney git://github.com/weierophinney/zf2.git
[user@workstation zf2 (master)]$ git remote add ralphschindler git://github.com/ralphschindler/zf2.git
[user@workstation zf2 (master)]$ git remote add EvanDotPro git://github.com/EvanDotPro/zf2.git
[user@workstation zf2 (master)]$ git remote add DASPRiD git://github.com/DASPRiD/zf2.git
[user@workstation zf2 (master)]$ git remote add akrabat git://github.com/akrabat/zf2.git

Keeping everything up-to-date

To help make your life easier, you’ll want to keep your local master branch up-to-date with the canonical ZF2 repository at a fairly regular interval. I tend to do this any time before I start a new branch, or at least once per day otherwise.

Assuming you already have master checked out, run:

[user@workstation zf2 (master)]$ git fetch upstream
[user@workstation zf2 (master)]$ git merge --ff-only upstream/master

Git loves to provide a short-cut for everything, so running this will yield the same result:

[user@workstation zf2 (master)]$ git pull --ff-only upstream master

Why the --ff-only? Well, it’s really just a precaution. Basically, your master branch should always just be a mirror of the upstream master branch, so this particular merge should always perform a fast-forward (not resulting in a merge commit). By adding the --ff-only option, you tell Git to abort the merge if it is not able to do a clean fast-forward from upstream/master. In my opinion, this is the single safest way to update your local master branch.

Now that your local master branch is up to date, it’s also a good idea to update the master branch on your public fork on GitHub by pushing:

[user@workstation zf2 (master)]$ git push origin master

Next, you’ll likely want to follow the development of your fellow developers (you know, those folks we added remotes for above). Getting all of their latest work is easy. Simply run:

[user@workstation zf2 (master)]$ git fetch --all

After that, you’ll have all of their latest branches and commits available locally. At this point you’ll be able to check out any branch or specific commit hash from any of the remote forks you added earlier.

Start working!

All work should be done in topic branches. For new features, you can name your branch feature/some-new-thing and for bug fixes, you can name your branch hotfix/BUGID-andor-description. You’ll generally always want to branch from master, and it’s a good idea to update your local master branch with upstream prior to branching (see above).

So, let’s say start our feature branch:

[user@workstation zf2 (master)]$ git checkout -b feature/bacon

Now you can do some work and make some commits! I recommend that you commit and push early and often. This will help other developers follow what you’re doing and what progress is (or is not) being made.

To explicitly push just the one feature branch, run:

[user@workstation zf2 (feature/bacon)]$ git push origin feature/bacon

To-Do

There are still quite a few topics I plan to add. To avoid an obnoxiously long blog post, I’ll probably break it into a few smaller posts. Here are some of the topics I still intend on covering:

  • Keeping your branch on top of master with git-rebase (and the caveats of doing so). In the meantime, read a simple explanation of git-rebase.
  • Preparing and submitting a pull request
  • Cleaning up branches once your pull request has been merged
  • For those with canonical access, I plan on covering a successful and safe work-flow for reviewing and merging pull requests.

One Response to “Keeping a clean GitHub fork – Part 1”

  1. Thanks! Very useful post. Do you plan to continue this theme?

Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre user="" computer="" color="" escaped="">