Skip to content

Instantly share code, notes, and snippets.

Created August 13, 2012 16:12
Show Gist options
  • Save piscisaureus/3342247 to your computer and use it in GitHub Desktop.
Save piscisaureus/3342247 to your computer and use it in GitHub Desktop.
Checkout github pull requests locally

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 =

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 =
	fetch = +refs/pull/*/head:refs/remotes/origin/pr/*

Now fetch all the pull requests:

$ git fetch origin
 * [new ref]         refs/pull/1000/head -> origin/pr/1000
 * [new ref]         refs/pull/1002/head -> origin/pr/1002
 * [new ref]         refs/pull/1004/head -> origin/pr/1004
 * [new ref]         refs/pull/1009/head -> origin/pr/1009

To check out a particular pull request:

$ git checkout pr/999
Branch pr/999 set up to track remote branch pr/999 from origin.
Switched to a new branch 'pr/999'
Copy link

xuexb commented Oct 26, 2017

Thank you~

Copy link

gondre commented Nov 7, 2017


Copy link

mbzt commented Nov 11, 2017

Thank you for this. For a reason I don't know I couldn't retrieve only the PR of interest to me, but this approach worked nicely.

Copy link

Thanks for this buddy!

Copy link


Copy link

❤️ it . Github should put it in their official documentation

Copy link

Someone should write a script to make this change. Also, this doesn't work for submodules that have a .git directory in a parent directory

Copy link

yog3ndra commented May 7, 2018


Copy link

ghost commented Jun 1, 2018

Thank you! 👍

Copy link

jeremydouglass commented Jul 28, 2018

If you want to resurrect a Pull Request that is displaying unknown repository after the fork was deleted then you can do that using the PR checkout gist here.

@aspiers has a comment post about how:

"Pull request displays "unknown repo" after deletion of fork #168"
isaacs/github#168 (comment)

Copy link

glensc commented Aug 21, 2018


i created repo containing the script that is able to checkout one specific PR:

Copy link

This works for VSTS/TFS as well. The differences:

[remote "origin"]
	url = <repo url>
	fetch = +refs/heads/*:refs/remotes/origin/*
	fetch = +refs/pull/*:refs/remotes/pull/*

and then git checkout --progress --force refs/remotes/pull/119/merge, where 119 is the PR number.

Copy link

fierval commented Sep 22, 2018

🥇 Timeless! Thank you!

Copy link

Just for fetching only one pull request. Handy, if you're hacking on something.

git fetch origin pull/7324/head:pr-7324
origin points to the remote server.
pull/7324/head is the remote pull request.
pr-7324 is the local pull-request branch.


Copy link

WOW! Very handy!
Thanks @piscisaureus

Copy link

Cool. But is there a way to checkout the actual result from the PR?
I mean, have the code on the destination (like master) and also the new code from the PR?

Copy link

Thanks much - this is exactly what I needed to know! Now I can test a PR locally before merging into the main repo.

Copy link

Tas-sos commented May 21, 2020

Very nice hack and discussion!
Thank you all! 🚀

Copy link

Lovely. Thank you.

Copy link

Lifesaver, thank you <3

Copy link

This is a great way to know if a commit is contained by some GitHub PR branch and won't be garbage collected!

Here's an example I went through: in a wiki I pasted several links to github repo files, using a specific hash abc in the URL in case the files was refactoring later. These commits might or might not have been part of some PR where Irebased and force-pushed over the PR branch, so I wasn't sure if this commit was still referenced by some branch, or might someday get deleted.

Running git branch -r --contains abc to search all remote commits didn't show anything, but git branch -r doesn't include all the refs/pull/* so that's not surprising. I could manually checkout relevant commits in git ls-remote and look through the logs to find abc as a parent, but that is error-prone. Making the .git/config change above, git fetch, then running git branch -r --contains abc outputed origin/pr/58 so that answered my question.

Copy link

I think it's not possible but still confirming if there is a way to check PR's title locally

Copy link

@subhamkumar-oyo testing this out, the PR branch only has the commits, and not the PR title. By default the PR title will be the commit title, but that's not guaranteed. Instead, you need to query for the PR title using the GitHub API, which is simple using the gh1 cli:

~/code/FireSocket $ gh pr list --state merged | grep 7.3.1
13	chore(deps): update dependency eslint to v7.3.1	renovate/eslint-7.x	MERGED

Copy link

This is helpful :)

Copy link


Copy link

A decade later this gist is still super useful. I review homework PRs and this workflow makes that a breeze. Thank you @piscisaureus!!

Copy link

yuis-ice commented Feb 2, 2022

Very cool.

Copy link

matu3ba commented Feb 13, 2022

I had to make a small correction for multiple remotes: git checkout upstream/pr/999, which would be nice to add for completeness.
This is much more compact than the github help page.

Copy link

nebbish commented Sep 13, 2022

There is an implementation "oddity" within Git about how this works. The new line added to the [remote "origin"] section does not have to be appended as the last line of that section. It could be inserted as the first line of that section.

Miraculously this makes a difference!

If you get the order correct -- then git pull just works after git checkout pr/1234 😃
This S.O. answer has the details.

No matter what though, as @dougludlow points out, git pull origin refs/pull/1234/head should work even if your config value is not correct.

Copy link

Is this a reasonable python script to clone a repo and add the PR's ?

import subprocess
import os
from git import Repo

def clone_and_configure(github_url, local_path):
    # Perform the initial Git clone
    if os.path.exists(local_path):
        print(f"Local repository already exists in {local_path}. Skipping clone.")
        # Perform the initial Git clone['git', 'clone', github_url, local_path])
        print(f"Repository cloned to {local_path}.")

    git_path = f'{local_path}/.git/'

    repo = Repo(git_path)
    # Read the existing Git configuration

    repoconfig = repo.config_reader()  # Get a config reader for read-only access.
    if any('origin' in key for key in repoconfig.sections()):
        print("found a section with origin")
        for section_name in repoconfig.sections():
            if 'origin' in section_name:
                fetch_line = '+refs/pull/*/head:refs/remotes/origin/pr/*'
                # Which to use ?
                #fetch_line = '+refs/pull/*/head:refs/gh-pull/remotes/origin/*'
                repo.git.config('--add', f'remote.origin.fetch', fetch_line)
                # Update the URL if needed
                repo.remote('origin').set_url(github_url)['git', 'fetch','origin', local_path])['git', 'fetch', 'origin'], cwd=local_path)

def main():
    # Specify your GitHub project URL
    github_url = ''  # Replace with your project URL
    # Specify the local path where you want to clone the repository
    local_path = 'C:/Users/Simon/Desktop/google-image-downloader'  # Replace with your desired local path

    # Perform the initial Git clone and configure
    clone_and_configure(github_url, local_path)

if __name__ == "__main__":

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment