Skip to content

Instantly share code, notes, and snippets.

@piscisaureus
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 = [email protected]: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 = [email protected]:joyent/node.git
	fetch = +refs/pull/*/head:refs/remotes/origin/pr/*

Now fetch all the pull requests:

$ git fetch origin
From github.com:joyent/node
 * [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'
@xuexb
Copy link

xuexb commented Oct 26, 2017

Thank you~

@gondre
Copy link

gondre commented Nov 7, 2017

Thanks!

@mbzt
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.

@agilewarealok
Copy link

Thanks for this buddy!

@kistters
Copy link

THX

@nishantrayan
Copy link

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

@colonelpanic8
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

@yog3ndra
Copy link

yog3ndra commented May 7, 2018

👍

Copy link

ghost commented Jun 1, 2018

Thank you! 👍

@jeremydouglass
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)

@glensc
Copy link

glensc commented Aug 21, 2018

hi

i created repo containing the script that is able to checkout one specific PR: https://gitlab.com/glensc/git-mr

@craigeddy
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.

@fierval
Copy link

fierval commented Sep 22, 2018

🥇 Timeless! Thank you!

@Albosonic
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.

👍

@Vehmloewff
Copy link

WOW! Very handy!
Thanks @piscisaureus

@thiagomgd
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?

@codelady7
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.

@Tas-sos
Copy link

Tas-sos commented May 21, 2020

Very nice hack and discussion!
Thank you all! 🚀

@lingyu77
Copy link

Lovely. Thank you.

@adamkobor
Copy link

Lifesaver, thank you <3

@darthwalsh
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.

@subhamkumar-oyo
Copy link

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

@darthwalsh
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

@kindlehl
Copy link

This is helpful :)

@msaroufim
Copy link

❤️

@patgarcia
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!!

@yuis-ice
Copy link

yuis-ice commented Feb 2, 2022

Very cool.

@matu3ba
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.

@nebbish
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 branch.pr/1234.merge config value is not correct.

@simonmcnair
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.")
    else:
        # Perform the initial Git clone
        subprocess.run(['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)
    
    #subprocess.run(['git', 'fetch','origin', local_path])
    subprocess.run(['git', 'fetch', 'origin'], cwd=local_path)


def main():
    # Specify your GitHub project URL
    github_url = 'https://github.com/hardikvasa/google-images-download'  # 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__":
    main()

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