Last Updated: December 14, 2017
· dexterous

GitHub: add remote for pulls and merges

After looking at @filosottile's totally awesome protip demonstrating how to checkout a pull request as a branch I got to thinking that there has to be a better way to do this than having to hammer out that whole refspec every time.

Initially I looked for ways to specify multiple refspecs for the fetch attribute for the GitHub remote...

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

... but, AFAICT, the fetch attribute takes just the single refspec. Then it struck me, if we can't add more refspecs to a remote, maybe we could just add more remotes! So I fired up git config -e and did this...

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

[remote "origin-pull"]
    url = git@github.com:user/repo.git
    fetch = +refs/pull/*/head:refs/remotes/origin-pull/*

[remote "origin-merge"]
    url = git@github.com:user/repo.git
    fetch = +refs/pull/*/merge:refs/remotes/origin-merge/*

... et viola! A git remote update gave me this...

$ git remote update
Fetching origin
Fetching origin-pull
From github.com:user/repo
 * [new ref]         refs/pull/1/head -> origin-pull/1
Fetching origin-merge
From github.com:user/repo
 * [new ref]         refs/pull/1/merge -> origin-merge/1

Now I can merge/rebase commits from GitHub pull requests without having to add a remote for the author's fork (and without having to remember that refspec. Given that GitHub closes issues once you merge and push to the branch, this makes for some cool pull request handling using just git tools!

PS- I'm pretty sure we can also extend this to cover git-notes.

5 Responses
Add your response


hmmm pretty savvy buddy. I like this idea. nice tip :)

over 1 year ago ·

@jwebcat Thanks. Anything to keep from leaving the shell! ;)

over 1 year ago ·

How about a single pr remote with fetch attribute below:

fetch = +refs/pull/*:refs/remotes/pr/*
over 1 year ago ·

I don't believe that would work as refs/pull/* would not refer to a specific ref.

over 1 year ago ·

You can just add lines like these instead:
[remote "origin"] url = git@github.com:user/repo.git fetch = +refs/heads/*:refs/remotes/origin/* fetch = +refs/pull/*/head:refs/remotes/origin/pull-requests/* fetch = +refs/pull/*/merge:refs/remotes/origin/pull-merges/*
This can be a problem if people actually commit changes into pull-requests/new-feature or something..

over 1 year ago ·