Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Testing a pull request, then merging locally; and avoiding TOCTOU

It's not immediately obvious how to pull down the code for a PR and test it locally. But it's pretty easy. (This assumes you have a remote for the main repo named upstream.)

Getting the PR code

  1. Make note of the PR number. For example, Rod's latest is PR #37: https://github.com/Psiphon-Labs/psiphon-tunnel-core/pull/37

  2. Fetch the PR's pseudo-branch (or bookmark or rev pointer whatever the word is), and give it a local branch name. Here we'll name it pr37:

$ git fetch upstream pull/37/head:pr37
  1. Switch to that branch:
$ git checkout pr37
  1. Compile and test.

If the PR code changes and you want to update:

# Do this while in the pr37 branch
$ git pull upstream pull/37/head

(I try to avoid pull and instead use fetch+merge, but... I don't know how to do it for this.)

Merging the PR

You can use the Github web interface, but there's a TOCTOU problem: If the pull-requester changes their master (or whatever they're PRing from) between the time you test and the time you merge, then you'll be merging code that you haven't reviewed/tested. So let's do it on the command line.

First, checkout the upstream master code:

You'll only do this the first time -- it creates the local upstream_master branch, tracks it to upstream_master, and switches to the branch:

$ git checkout -t -b upstream_master upstream/master

After the first time you'll just do:

$ git checkout upstream_master

Now merge the PR:

$ git merge pr37

NOTE: You should edit the merge commit message to reference the PR (using, say #37 in it).

Now push:

$ git push upstream HEAD:master

(You can't just git push because your local branch name is different than the remote.)

Done! Refresh the Github PR page and you'll see that the PR is now merged+closed.

@holgerbrandl

This comment has been minimized.

Copy link

@holgerbrandl holgerbrandl commented Feb 27, 2017

In section "getting the PR code : (2)" is should be origin and not upstream (as in the referenced original docs

@aslafy-z

This comment has been minimized.

Copy link

@aslafy-z aslafy-z commented Nov 16, 2018

@holgerbrandl Looks that you missed this from the intro.

(This assumes you have a remote for the main repo named upstream.)

@mlbloxer

This comment has been minimized.

Copy link

@mlbloxer mlbloxer commented Mar 26, 2019

Thank you so much

@AIRyndon

This comment has been minimized.

Copy link

@AIRyndon AIRyndon commented Jun 3, 2019

Thank you for this Adam :)

I have a question..when you are about to merge, do we really need a branch, which is copy of upstream master for this to work?

git checkout -t -b upstream_master upstream/master

or can we just checkout an existing master already tracked and merge the pull request on that one?

git checkout master
git merge pr37
git push

@lazarillo

This comment has been minimized.

Copy link

@lazarillo lazarillo commented Nov 13, 2019

Thank you for this Adam :)

I have a question..when you are about to merge, do we really need a branch, which is copy of upstream master for this to work?

git checkout -t -b upstream_master upstream/master

or can we just checkout an existing master already tracked and merge the pull request on that one?

git checkout master
git merge pr37
git push

Yes, I also do not understand why this step is necessary. (I wanted to just upvote @AIRyndon, but it seems you cannot do that in gist.

@adam-p

This comment has been minimized.

Copy link
Owner Author

@adam-p adam-p commented Nov 13, 2019

@AIRyndon @lazarillo git checkout master will get you your local branch named master, which might track origin and/or might not be up-to-date, etc. The upstream_master thing is kind of hacky, but it assures me that I'm working on upstream/master.

My git-fu is not super strong and I'm happy to be corrected, though.

@kreig303

This comment has been minimized.

Copy link

@kreig303 kreig303 commented Mar 27, 2020

for the "fetch + merge" part... from memory:

% git checkout pr37
% git fetch upstream pull/37/head
% git merge upstream/pull/37/head

haven't actually tried the analogue but this should work :)

@wadkar

This comment has been minimized.

Copy link

@wadkar wadkar commented Apr 11, 2020

for the "fetch + merge" part... from memory:

% git checkout pr37
% git fetch upstream pull/37/head
% git merge upstream/pull/37/head

haven't actually tried the analogue but this should work :)

This is the proverbial "update the PR #37 locally" piece. You can test pr37 or merge it on some other branch etc.

@mcascone

This comment has been minimized.

Copy link

@mcascone mcascone commented Jun 5, 2020

Is it possible to use this to test a Pull Request build locally in Jenkins?
I'm not sure how the internals work, but i want to test a PR build locally, using git, without having to create the PR on my org's actual GitHub.

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