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