Update: You can fetch pull requests without using a script like the kind described in this article. See the use of
git fetch in this article for details.
I publish the source-code for a lot of my programming projects on GitHub. Sometimes I am fortunate enough to receive pull requests for said projects. I use the word ‘fortunate’ because personally one of my favorite aspects of open-source development is when someone spends their personal time to contribute to and improve one of your projects. Personally I receive the most pull requests for PHP Mode, and so I have a simple script for Git which I use to fetch those pull requests, which I want to share today.
Here is the Perl script I wrote,
#!/usr/bin/env perl use v5.14; my $id = shift @ARGV; my $remote_url = qx(git config --null --get remote.origin.url); $remote_url ~~ /.+?github.com:(.+)\.git/i; my $pull_request_url = "https://github.com/$1/pull/$id.patch"; my $branch_name = "github/pr/$id"; qx(git checkout -b $branch_name); qx(curl $pull_request_url | git am -s); __END__
I use the script as part of a Git alias:
git config --global alias.cpr "!perl /home/eric/Scripts/Git/github-cpr.pl"
Now if someone opens a pull request on a project I can fetch the commits for that pull request with the command
git cpr 98, where the number is assigned by GitHub.
The URI for pull requests on GitHub looks like this:
That number at the end is the argument which I give to the script. The script also makes the assumption that my repository’s
origin remote matches the
$remote_url regular expression from the script. That regular expression has one capture group: it grabs my username and project name from the URL. So in the example URL above it captures the
ejmr/php-mode portion; I do not assign this to a separate variable in the script but simply reference it as
Using that and the pull request number the script builds the
$pull_request_url string. Note well that it suffixes
.patch to the URL. If we add that to the end of a pull request URL then GitHub will return the pull request content in a format we can feed directly into the
git-am command, which is exactly what the script does.
However, before applying the commits of the pull request, the script will create and checkout a new branch, forked from the current branch. This is the origin of the name
cpr: ‘checkout pull request’. That branch will have the name
github/pr/98, using whatever number GitHub gave to the pull request.
So after running the command I will find myself on a new branch with all of the patches from the pull request. From there I can test and review them, deciding whether to merge them or if I need to ask the contributor for additional feedback. Note that my script uses the
-s option with
git-am; this adds a
Signed-off-by line with my name to each commit in the pull request. Personally I prefer to sign-off on commits as a way of indicating that I reviewed and tested the patches, like so.
And That’s It
There is not much to the Perl script so I hope that explained everything, but if not please don’t hesitate to ask. If you get pull requests for GitHub projects then you may find this useful, and if so I’d love to know and would happily welcome any improvements. If you have a different way you prefer to handle pull requests then I’d enjoy hearing about that as well. Git certainly allows for different workflows and I’ve found it educational over the years to listen to how other people manage their repositories.