Imagine that someone has sent you a pull request from a fork of your repository. Here's how you can check out the changes on your local machine to verify that everything is a-okay.

Modifying your Git configuration

Open your .git/config file in your editor and locate the section for your GitHub remote. It should look something like this:

[remote "origin"]
  url = git@github.com:<USERNAME>/<REPO_NAME>.git
  fetch = +refs/heads/*:refs/remotes/origin/*

We're going to add a new refspec to this section so that it now looks like this:

[remote "origin"]
  url = git@github.com:<USERNAME>/<REPO_NAME>.git
  fetch = +refs/heads/*:refs/remotes/origin/*
  fetch = +refs/pull/*/head:refs/pull/origin/*

What did we just do? We told Git that we would like to fetch remote references that match the pattern refs/pull/*/head and write them as local references that match the pattern refs/pull/origin/*. We also indicated (using the + prefix) that we'd like Git to update references even if they aren't fast-forwards.

Now we can fetch all the pull requests:

git fetch origin
# From github.com:joyent/node
# * [new ref]         refs/pull/1000/head -> refs/pull/origin/1000
# * [new ref]         refs/pull/1002/head -> refs/pull/origin/1002
# * [new ref]         refs/pull/1004/head -> refs/pull/origin/1004
# * [new ref]         refs/pull/1009/head -> refs/pull/origin/1009

Notice how the remote references are rewritten locally.

A few caveats:

  1. The remote refs/pull/ namespace is read-only. Do not try to push any commits there; they will be rejected.
  2. Your local refs/pull/origin/ namespace will not be affected by calls to git-remote. In other words, it will not change when you remove or rename a remote reference.

Checking out a particular pull request

You should now be able to check out a pull request in your local repository as follows:

git checkout -b 999 pull/origin/999
# Switched to a new branch '999'