259

Pull Requests are great for understanding the larger thinking around a change or set of changes made to a repo. Reading pull requests are a great way to quickly "grok" a project as, instead of small atomic changes to the source, you get larger groupings of logical changes. Analogous to organizing the lines in your code into related "stanzas" to make it easier to read.

I find myself looking at a file or a commit, and I wonder if there is a way to backtrack the commit to the Pull Request that originally created it. That Pull Request would have been merged eventually, but not necessary with a merge-commit.

Pang
  • 9,564
  • 146
  • 81
  • 122
DragonFax
  • 4,625
  • 2
  • 32
  • 35
  • 2
    +1 This is also useful if you forked a project and have an old work branch sitting around and you no longer remember if you ever made a PR for it. – Steve Clay Sep 13 '13 at 14:22

9 Answers9

347

You can just go to GitHub and enter the SHA into the search bar, make sure you select the "Issues" link on the left.

UPDATED 13 July 2017

Via the GitHub UI there is a now a really easy way to do this. If you are looking at a commit in the list of commits in a branch in the UI, click on the link to the commit itself. If there is a PR for that commit and it wasn't added directly to the branch, a link to the PR listing the PR number and the branch it went into will be directly under the commit message at the top of the page. enter image description here


Example of finding a PR by clicking on a link to the commit

If you have the commit SHA and nothing else and don't want to go digging around for it, just add /commit/[commit SHA] to the repo url, and you will see the commit page, with the PR link if it exists. For example, if the SHA is 52797a7a3b087231e4e391e11ea861569205aaf4 and the repo is https://github.com/glimmerjs/glimmer-vm , then go to https://github.com/glimmerjs/glimmer-vm/commit/52797a7a3b087231e4e391e11ea861569205aaf4

Pang
  • 9,564
  • 146
  • 81
  • 122
RustyToms
  • 7,600
  • 1
  • 27
  • 36
  • I can't get this to work with a short SHA like `e4077951`, does this still work for you? – Matt Sanders Jan 12 '16 at 21:38
  • @RustyToms this works, but when I searched a commit hash like you mentioned, [https://github.com/wso2/carbon-kernel/search?q=209775e3324be16dc78a36d67de7cb860f83d0a0&type=Issues&utf8=%E2%9C%93] it provide me two Pull request both has merged the same commit to the master. In such kind of scenario what we should select as the Pull request that merged the relevant commit – Kasun Siyambalapitiya Jan 03 '17 at 09:30
  • @RustyToms how can we acheive this through the API – Kasun Siyambalapitiya Jan 04 '17 at 04:24
  • 1
    If there is no reference to a PR, can I conclude there was no PR? That is, the commit was made directly on the branch (usually `master`)? – Erik May 07 '18 at 11:23
  • I think so @Erik – RustyToms Nov 02 '19 at 18:37
  • Our repo is setup to rebase the PR commits, and I find it's only the last commit in the PR that has this label and link. Is that other people's experience? It's quite annoying, as you can find one commit but then you have to trawl the commit history to find which of the later commits was the last one in the PR. – Rikki Apr 14 '23 at 16:33
  • I've just deciphered this is because of the Rebase and Merge means the commit SHA in the branch pre-merge is different from the commit SHA post-merge. Because I just see the file in the main repo, I don't know what branch or SHA it was before the PR was merged, which makes it near impossible to search for. – Rikki Apr 14 '23 at 16:43
69
git config --add remote.origin.fetch +refs/pull/*/head:refs/remotes/origin/pull/*
git fetch origin
git describe --all  --contains <COMMIT>

If necessary, change origin to the name of the remote that points to the GitHub repository to which the pull request would have been sent. The first command only needs to be run once for any given remote, and the second will generally be done when getting other updates.

This will cause git to get information about pull requests along with actual branches. They'll show up as remote-tracking branches like origin/pull/123. Once that is done, you can use git describe with the --all and --contains options to show the first branch which has the referenced commit.

However, this won't work if the commit you're looking for is actually a modified version of the commit from the pull request such as if the changes were rebased onto other work or the person doing the merge decided to make some changes.

Pang
  • 9,564
  • 146
  • 81
  • 122
qqx
  • 18,947
  • 4
  • 64
  • 68
  • I assume this results in downloading all commits in rejected PRs. Is there no way to have fetch get the list of `pull/*/head` commits without the blobs? How would one "clean up" after this (reconfigure the origins)? – Steve Clay Sep 13 '13 at 14:20
  • 1
    This is great to know; I had no idea GitHub tracked these as actual Git objects but it makes perfect sense. BTW did you mean to use "upstream" instead of "origin" on your config command? – Tobias J Jan 29 '14 at 21:43
  • 1
    @TobyJ The use of `upstream` was indeed a mistake. I'd copied that from a repository that had that config where the remote was named `upstream` and missed that occurrence when changing it to use the more common `origin` as the name of the remote. I`ve edited the answer to fix that. – qqx Jan 30 '14 at 00:32
  • fwiw you can also try using `refs/remotes/origin/pr/*` instead of `refs/remotes/origin/pull/*` – elaichi Jan 09 '17 at 19:29
  • Once you get the branch name you can use github's "head" parameter to get the associated PR - see https://developer.github.com/v3/pulls/#parameters – Almenon Mar 08 '19 at 03:02
  • 3
    I'd like to point out that this won't work if you select "Delete branch" on the PRs when you're done. I do this for cleanup. Really unfortunate. – Steven Linn Feb 07 '20 at 21:15
  • @StevenLinn It seems to work now even for deleted branches. – marknuzz Aug 29 '22 at 18:38
23

Since Oct. 13, 2014, this should be straightforward:

For example:

You can see for the file hakimel/reveal.js/plugin/markdown/markdown.js, my contribution now comes with a reference to the PR #734 it originated.

PR from contrib

This comes from Linking merged pull requests from commits:

We've been including the containing branches and tags on commit pages to give you more context around changes. Now, commits in a repository's default branch will also show you the pull request that introduced them.

commit with PR reference in it!

In the pull request, you can see the discussion around why the commit was introduced, and get a clearer picture of the reason for the change.

As always, if you know the commit SHA, you can skip the commit page and search for the pull request directly.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • when I searched a commit hash like you mentioned, [https://github.com/wso2/carbon-kernel/search?q=209775e3324be16dc78a36d67de7cb860f83d0a0&type=Issues&utf8=%E2%9C%93] it provide me two Pull request both has merged the same commit to the master. In such kind of scenario what we should select as the Pull request that merged the relevant commit – Kasun Siyambalapitiya Jan 03 '17 at 09:37
  • @KasunSiyambalapitiya Not sure: you could ask a new question for that. I would go with the most recent. – VonC Jan 03 '17 at 10:38
  • 2
    can we obtain this in `API` level? – Kasun Siyambalapitiya Jan 19 '17 at 06:30
  • @KasunSiyambalapitiya Good question. I don't know. I don't see that reference in https://developer.github.com/v3/repos/commits/#get-a-single-commit – VonC Jan 19 '17 at 09:38
  • @esp Interesting. I see a list of PR, but not their SHA1 commit marking their integration. – VonC Jun 08 '17 at 22:34
  • @VonC I see "the list" with one PR that has commit in question – esp Jun 09 '17 at 00:37
  • @esp Strange: I see 30 objects, with no commit: https://i.stack.imgur.com/wQmFL.png – VonC Jun 09 '17 at 05:59
  • Are you using full commit sha? – esp Jun 09 '17 at 20:01
  • @esp Yes. I do see now a link to an issue which in turn has a link to the PR – VonC Jun 09 '17 at 20:28
22

Put the commit hash into the Pull Request filters field on GitHub.

enter image description here

Dan Rosenstark
  • 68,471
  • 58
  • 283
  • 421
12

You can also do this using the gh cli, here's an example:

gh pr list --search "30aedc5aaab4708b2144c648a9c7ace9aff4cd31" --state merged --json url --jq '.[0].url'

For more info, see - https://cli.github.com/manual/gh_pr_list

Sher Chowdhury
  • 131
  • 1
  • 2
3

I had this same problem and wrote the pr_for_sha bash helper, documented here:

http://joey.aghion.com/find-the-github-pull-request-for-a-commit/

Call it like pr_for_sha <COMMIT> and it will open the corresponding github pull request page in a browser.

Joey
  • 439
  • 2
  • 6
  • 2
    This solution assumes that the nearest merge following the commit is the merge that contains the commit, which is not necessarily always the case. – Jason Denney May 18 '15 at 20:36
  • @JasonDenney By following you mean in the given branch or in time? – LeZuse Mar 03 '17 at 18:22
  • Hmm, this was a while ago, but I think I meant in time. Say on Monday you make a commit "X" in branch A, Tuesday you make a commit in branch B and merge branch B to master, Wednesday you merge branch A to master. If you used this script to do a search while on the master branch for which PR commit "X" was in, I'm pretty sure it'd incorrectly tell you branch B. Double check for yourself though. – Jason Denney Mar 04 '17 at 19:08
  • Can't get the `git log` command to work. `git log --merges --ancestry-path --oneline 66100ab0..master` -- `fatal: ambiguous argument '66100ab0..master': unknown revision or path not in the working tree.` -- `git version 2.25.0` – Gianfranco P. Jun 18 '20 at 13:57
2

This command retrieves the pull request number associated with a specific commit hash.

Here's how it works:

  1. git ls-remote lists all the remote references for a Git repository.

  2. The grep command filters the results to only show references that include the commit hash $SHA_COMMIT_ID.

  3. awk processes the filtered results and extracts the pull request number from the reference string. The split function splits the reference string by forward slashes, and the print command outputs the third element of the resulting array, which is the pull request number.

  4. The pull request number is stored in the $PR_NUMBER variable, and a message is printed to the console that displays the pull request number.

export PR_NUMBER=$(git ls-remote |grep '$SHA_COMMIT_ID'|awk '/refs\/pull\/.*\/./{split($2,a,"/");print a[3]}') 
echo "PR Number: $PR_NUMBER" 
Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
1

I've been a heavy user of the cheeky little link on the GitHub web UI but wanted a faster way that would take me straight there from the terminal, basically a git pr SHA command. It took a bit of doing, but here's a series of git aliases that will set that up for you on MacOS:

  git config --global alias.merge-commits '!funct() { git log --merges --reverse --oneline --ancestry-path $1..origin | grep "Merge pull request";  }; funct'
  git config --global alias.pr-number '!funct() { git merge-commits $1 | head -n1 | sed -n "s/^.*Merge pull request #\\s*\\([0-9]*\\).*$/\\1/p"; }; funct'
  git config --global alias.web-url '!funct() { git config remote.origin.url | sed -e"s/git@/https:\/\//" -e"s/\.git$//" | sed -E "s/(\/\/[^:]*):/\1\//"; }; funct'
  git config --global alias.pr '!funct() { open "`git web-url`/pull/`git pr-number $1`" ;}; funct'

If you're on Linux, replace open with xdg-open and you're golden. It shouldn't be too difficult to adapt to work with GitLab either.

Note this will only work if you practicing GitHub flow and creating explicit merge commits.

I've written a more detailed explanation of how this all works here: https://tekin.co.uk/2020/06/jump-from-a-git-commit-to-the-pr-in-one-command

tekin
  • 11
  • 1
0

I wanted something similar to find a PR for a given commit, then comment on the PR with Jenkins build info. Here's how that works using GH API:

# for a given SHA and repo
SHA=58d8b4407ab5d2b9a696236202308d92d3e25340
ownerRepo=redhat-developer/devspaces

# a. use gh to query a given repo for closed pulls for a given commitSHA; return the PR URL
PR_COMMENTS_URL=$(curl -sSL -H "Authorization: token ${GITHUB_TOKEN}" -H "Accept: application/vnd.github.v3+json" \
    "https://api.github.com/repos/${ownerRepo}/pulls?state=closed" | \
    yq -r --arg SHA "$SHA" '.[]|select(.head.sha == $SHA)|.comments_url')

# b. comment on the PR by URL: https://api.github.com/repos/redhat-developer/devspaces/issues/848/comments
if [[ $PR_COMMENTS_URL ]]; then
    curl -sSL -H "Authorization: token ${GITHUB_TOKEN}" -H "Accept: application/vnd.github.v3+json" \
        -X POST -d '{"body": "Building in currentBuild.absoluteUrl (GH API TEST)"}' "${PR_COMMENTS_URL}" | yq -r '.html_url'
fi

Then you can wrap this script inside a Jenkins groovy/bash block, and pass in currentBuild.absoluteUrl from the running build to the GH pull request.

Equivalent code using gh cli:

# 0. install gh CLI
sudo yum -y -q install https://github.com/cli/cli/releases/download/v2.20.2/gh_2.20.2_linux_amd64.rpm

# a. use gh to query a given repo for merged PRs for a given commitSHA; return the PR URL
PR_HTML_URL=$(gh pr list --repo ${ownerRepo} --state merged --json url --jq '.[].url' \
    --search $SHA)

# b. comment on the PR by URL: https://github.com/redhat-developer/devspaces/pull/848
if [[ $PR_HTML_URL ]]; then
    gh pr comment $PR_HTML_URL -b "Building in currentBuild.absoluteUrl (GH CLI TEST)"
fi

For a sample of Jenkins pipeline code:

https://gist.github.com/nickboldt/efb8d1b3a60c079e46b5b7aab4412e22#file-commentonpr-fragment-jenkinsfile

nickboldt
  • 732
  • 1
  • 7
  • 13