1

I am working on a project which is maintained in Git, with a central repository on GitHub. I often review pull requests with the help of a local copy. While Git itself doesn't know anything about “pull requests”, GitHub makes the information available in a separate branch namespace. I've configured Git to fetch pull requests with a configuration like this:

[remote "origin"]
    url = git@github.com:octocat/hello-world.git
    fetch = +refs/heads/*:refs/remotes/origin
    fetch = +refs/pull/*/head:refs/remotes/origin/pull/head/*

Then I can check out PR #42 with git checkout origin/pull/head/42. So far so good.

If a pull request has been force-pushed after my initial review, I often want to compare the version that I reviewed with the new version. I would like to have something like origin/pull/head/42/1 referring to the latest commit before the first force-push, origin/pull/head/42/2 referring to the latest commit before the second force-push, etc. (I don't mind the exact names.) Is there any way to do this?

The problem has two parts:

  1. Get GitHub to tell me what the commit ID is for the pre-force-push tip of a pull request. This information appears on the web page (https://github.com/octocal/hello-world/pull/42 says “… force-pushed the mybranch branch from COMMIT1 to COMMIT2”), but I can't find it in the API.
  2. Teach Git that a certain commit should appear with a certain remote branch name, which may or may not be trivial depending on how (1) is done.

Is there a configuration or helper program that can give me easy access to old versions of GitHub pull requests, without having to copy-paste the commit ID from the web page and give it a local branch name?

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
  • I don't think you can get the information from GitHub in a proper machine-digestible form. You could scrape it out of the web page. Once you do get the information, the only way to *use* it is to fuss with the `fetch` lines: don't put in a general "fetch all PRs", put in one specific "fetch this one PR using this local name", per PR per iteration. Not very pretty, but should work fine. – torek May 10 '21 at 23:27
  • @Gilles - so did you find a way to do what you wanted? I'm facing the same problem, and I couldn't find any way to view older PR versions (let alone to compare between the versions)... – kliteyn Mar 15 '23 at 15:41
  • @kliteyn No. The best I can do is use the web page, expand all the “hidden items” bits, and read the shas from the “force-pushed the NAME branch from SHA” lines. Some of those lines are “force-pushed the NAME branch COUNT times, most recently from SHA” and in that case I don't know how to find the intermediate shas. For the shas you manage to find, `git fetch origin SHA` works (IIRC it didn't a few years ago, but nowadays it does, even for older pull requests where it didn't work then). – Gilles 'SO- stop being evil' Mar 15 '23 at 17:13

1 Answers1

1

There is an Events API, which lists actions that occurred on a repo, and returns events :

  • each individual event has a type : PushEvent, PullRequestEvent, CreateEvent ...

  • and a payload, which depends on its type ; for example :


A partial answer with local data : your local refs are also logged in the reflog, you can also look at what you have in git reflog origin/pull/head/42.

Obviously : the limitation of that solution is that you only see the points where running git fetch on your local repo updated that reference ; if someone has force pushed 3 times between two of your git fetch, your local reflog won't get updated 3 times.

LeGEC
  • 46,477
  • 5
  • 57
  • 104
  • I finally got around to trying this. It's a nice idea, but unfortunately, it doesn't work in practice. As far as I can tell, you can only get the most recent 300 events. For the project I'm most interested in, pull requests normally come from a fork (so you have to list the events from the fork), but even in a personal fork, most contributors are active enough that 300 events doesn't last nearly as long as a pull request. It's annoying that the information is mostly available on the web page (except with consecutive force-pushes), but i can't find it in the API. – Gilles 'SO- stop being evil' Sep 02 '21 at 16:19
  • Ok. Have you tried using your local reflog ? – LeGEC Sep 02 '21 at 18:50
  • 1
    The reflog only tells me about commits that I've pulled, and in practice that misses enough updates that it's not all that useful. Hmmm, now that I think of it, if I haven't pulled an update, then I probably haven't reviewed it, so for my use case it might be enough. I'll give a try at scripting that. Thanks for the ideas, in any case. – Gilles 'SO- stop being evil' Sep 02 '21 at 19:52
  • additionally : when you review a PR, you may place a tag stating "I reviewed that PR in that state" – LeGEC Sep 02 '21 at 19:56