Finding the Github Pull Request for a topic branch

Finding the Github pull request associated with a branch.

Work on a large enough project, with other people and sooner or later you’re going to find some commit, or branch, and want to know what was in the pull request that merged it in. Maybe you want to see what other commits got merged over at the same time. Maybe you want to see what the diff was at that point in time. But, how do you get from a branch name to a pull-request.

The key to solving this is knowing that pull requests are actually branches. They’re just… hidden branches. So, first you start tracking them…

Locate the section for your github remote in the .git/config file. It looks like this:

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = git@github.com:joyent/node.git

Now add the line fetch = +refs/pull/*/head:refs/remotes/origin/pr/* to this section. Obviously, change the github url to match your project’s URL. It ends up looking like this:

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = git@github.com:joyent/node.git
    fetch = +refs/pull/*/head:refs/remotes/origin/pr/*

Now, after a git fetch origin you can say git checkout pr/999 to checkout pull request number 999 as a local branch and diff it, or do pretty-much anything else with it.

Once you’ve got that set up, it’s just a matter of comparing your local topic branch to the other branches in your system to find other branches that point to whatever branch you’re interested in.

I use a shell script called git-find-twins which iterates over the known branches (including pull request branches) and finds any whose tree-ish matches that of the current branch. You can find the latest source here in Github.

[Note: My apologies for the disappearing code on the right side in these examples. Just grab the source from the link above.]

    #!/bin/sh
    # Finds other git branches whose HEADs point to the same 
    # treeish as this branch.

    # thanks to mockinterface on 
    # http://stackoverflow.com/a/20756047/13973
    # for showing how to do this.

    echo "Looking for branches pointing to: $(git rev-parse HEAD)"
    git for-each-ref --format="%(refname)" | \
        xargs -I refname   \
        sh -c '[[ $(git rev-parse HEAD^{tree}) == $(git rev-parse refname^{tree}) ]] && echo refname'
    echo "DONE"

Add that to your path, and make it executable then check out the branch you want to find the pull request for, and run your new shell script with git find-twins (note the space) and you’ll see output like this.

$ git find-twins
Looking for branches pointing to: cb3c2dcf606a0a26107131697dd37aef53d44aad
refs/heads/9284_vzw_bug_fixtures_without_fixture_types
refs/remotes/origin/9284_vzw_bug_fixtures_without_fixture_types
refs/remotes/origin/pr/530
DONE

That last one is what you want. 530 the number of the pull request, which you can put into an URL to see the pull request. Now, you’re probably saying “Yeah, but what URL?” well, one way to get the correct url is to just bring up any other pull request in the current project and change the number in the url. Or you can add this shell script, which I call url_for_pr which generates an url for the pull request number in the current repo. It’s based on the assumption that “origin” is the Github repo. If it isn’t you’ll need to tweak what remote it gets its info from. You can find the latest source here on Github

[Note: My apologies for the disappearing code on the right side in this example. Just grab the source from the link above.]

    #!/bin/sh
    # when run from a git repository, and passed the number 
    # for a pull request, it will generate an url for 
    # where to find it on Github. This assumes that
    # "origin" is pointing to the Github repo.
    # This will work with Github Enterprise too.

    if [ $# -eq 1 ]; then
        ROOT_URL=$(git config --get remote.origin.url | \
            sed s/.*@// |sed s/\.git// | sed s/\:/\\//)
        PR_NUM=$1
        echo "https://$ROOT_URL/pull/$1"
    else
        echo "Please pass in a Pull Request number"
        echo "Note that this should be run within a git repository"
    fi