{"thread":{"id":"44916","subject":"grep open pull requests","startedAt":"2017-01-19T18:13:31Z","lastAt":"2017-01-19T22:24:34Z","messageCount":4,"participants":["Jack Bates","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"309743","messageId":"276f6ed9-ff06-a00f-b88a-4d40d55c6d40@nottheoilrig.com","threadId":"44916","inReplyTo":null,"subject":"grep open pull requests","fromName":"Jack Bates","fromEmail":"bk874k@nottheoilrig.com","sentAt":"2017-01-19T18:12:03Z","receivedAt":"2017-01-19T18:13:31Z","isPatch":false,"sender":{"key":"bk874k@nottheoilrig.com","avatar":null},"body":"I have a couple questions around grepping among open pull requests.\n\nFirst, \"git for-each-ref --no-merged\": When I run the following,\nit lists refs/pull/1112/head, even though #1112 was merged in commit \nced4da1. I guess this is because the tip of refs/pull/1112/head is \n107fc59, not ced4da1?\n\nThis maybe shows my lack of familiarity with Git details,\nbut superficially the two commits appear identical -- [1] and [2] --\nsame parent, etc. Nonetheless they have different SHA-1s.\nI'm not sure why that is -- I didn't merge the commit --\nbut regardless, GitHub somehow still connects ced4da1 with #1112.\n\nSo my question is, how are they doing that,\nand why can't \"git for-each-ref --no-merged\" likewise\nconnect ced4da1 with refs/pull/1112/head?\n\n   $ git clone \\\n   >   --bare \\\n   >   --config remote.origin.fetch=+refs/pull/*/head:refs/pull/*/head \\\n   >   https://github.com/apache/trafficserver.git\n   $ cd trafficserver.git\n   $ git for-each-ref --no-merged\n\n\nMore generally, what I want is to periodically list open pull requests \nthat add or modify lines containing the string \"memset\". So far I have \nthe following in a Makefile. Can you recommend any improvements?\n\n.PHONY: all\nall: trafficserver.git\n\tcd trafficserver.git && git fetch\n\tcd trafficserver.git && git for-each-ref --format '%(refname)' \nrefs/pull --no-merged | \\\n\t  while read refname; do \\\n\t    git log -p \"master..$$refname\" | grep -q '^+.*memset' && echo \n\"$$refname\"; \\\n\t  done\n\ntrafficserver.git:\n\tgit clone \\\n\t  --bare \\\n\t  --config remote.origin.fetch=+refs/pull/*/head:refs/pull/*/head \\\n\t  https://github.com/apache/trafficserver.git\n\n\nLastly, a question more about GitHub than Git, but: Given the way GitHub \nis setup, I hope I can get a list of unmerged pull requests from Git \nalone. Can you think of a way to list *open* pull requests,\nor is that status only available out of band?\n\nThanks!\n\n\n[1] \nhttps://github.com/apache/trafficserver/commit/107fc59104cce2a4b527f04e7ac86695c98b568c\n[2] \nhttps://github.com/apache/trafficserver/commit/ced4da13279f834c381925f2ecd1649bfb459e8b\n"},{"id":"309755","messageId":"20170119190227.opjisryyqn766tqy@sigill.intra.peff.net","threadId":"44916","inReplyTo":"276f6ed9-ff06-a00f-b88a-4d40d55c6d40@nottheoilrig.com","subject":"Re: grep open pull requests","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2017-01-19T19:02:27Z","receivedAt":"2017-01-19T19:03:08Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jan 19, 2017 at 11:12:03AM -0700, Jack Bates wrote:\n\n> I have a couple questions around grepping among open pull requests.\n> \n> First, \"git for-each-ref --no-merged\": When I run the following,\n> it lists refs/pull/1112/head, even though #1112 was merged in commit\n> ced4da1. I guess this is because the tip of refs/pull/1112/head is 107fc59,\n> not ced4da1?\n\nRight. Git's `--no-merged` is about commit ancestry.\n\n> This maybe shows my lack of familiarity with Git details,\n> but superficially the two commits appear identical -- [1] and [2] --\n> same parent, etc. Nonetheless they have different SHA-1s.\n> I'm not sure why that is -- I didn't merge the commit --\n> but regardless, GitHub somehow still connects ced4da1 with #1112.\n\nThe commits differ only in the committer timestamp. Try:\n\n  diff -u <(git cat-file commit 107fc5910) \\\n          <(git cat-file commit ced4da132)\n\nIs it possible that somebody cherry-pick or rebased it? Looking at the\nhistory of apache/trafficserver, I don't see any merges, which implies\nto me that the project is using a rebase workflow to merge PRs.\n\nIt's much trickier to find from the git topology whether a particular\nhistory contains rebased versions of commits.  You can look at the\n--cherry options to \"git log\", which use patch-ids to try to equate\ncommits. Something like:\n\n  git for-each-ref --format='%(refname)' 'refs/pull/*/head' |\n  while read refname; do\n\tif test -z \"$(git rev-list --right-only --cherry-pick -1 origin...$refname)\n\tthen\n\t\techo \"$refname: not merged\"\n\tfi\n  done\n\nThat's obviously much less efficient than `--no-merged`, but it should\ngenerally work. The exception is if the rebase changed the commit\nsufficiently that its patch-id may have changed.\n\n> So my question is, how are they doing that,\n\nI suspect the answer is \"somebody clicked the rebase button GitHub\"\nwhich simultaneously did the rebase and marked the PR as merged.\n\n> Lastly, a question more about GitHub than Git, but: Given the way GitHub is\n> setup, I hope I can get a list of unmerged pull requests from Git alone. Can\n> you think of a way to list *open* pull requests,\n> or is that status only available out of band?\n\nThat information isn't reflected in the git topology. It's in GitHub's\ndatabase. You can ask the API:\n\n  https://developer.github.com/v3/\n\nThere are libraries to help with that:\n\n  https://developer.github.com/libraries/\n\nI think that's probably the best answer to your \"unmerged\" question,\ntoo. Ask the API which PRs are unmerged, and then do whatever git-level\nanalysis you want based on that.\n\n-Peff\n"},{"id":"309800","messageId":"9f59c0d7-73d3-1b4c-65ca-700d6e1f4f23@nottheoilrig.com","threadId":"44916","inReplyTo":"20170119190227.opjisryyqn766tqy@sigill.intra.peff.net","subject":"Re: grep open pull requests","fromName":"Jack Bates","fromEmail":"bk874k@nottheoilrig.com","sentAt":"2017-01-19T22:12:53Z","receivedAt":"2017-01-19T22:24:08Z","isPatch":false,"sender":{"key":"bk874k@nottheoilrig.com","avatar":null},"body":"On 19/01/17 12:02 PM, Jeff King wrote:\n> It's much trickier to find from the git topology whether a particular\n> history contains rebased versions of commits.  You can look at the\n> --cherry options to \"git log\", which use patch-ids to try to equate\n> commits. Something like:\n>\n>   git for-each-ref --format='%(refname)' 'refs/pull/*/head' |\n>   while read refname; do\n> \tif test -z \"$(git rev-list --right-only --cherry-pick -1 origin...$refname)\n> \tthen\n> \t\techo \"$refname: not merged\"\n> \tfi\n>   done\n>\n> That's obviously much less efficient than `--no-merged`, but it should\n> generally work. The exception is if the rebase changed the commit\n> sufficiently that its patch-id may have changed.\n\nCool, thanks for all your help! \"git log --cherry-pick\" works quite \nwell. One thing: I expected the following to be equivalent, but found \nthat they're not. Is that by accident or design?\n\n   $ git rev-list --cherry-pick --right-only master...refs/pull/1112/head\n   $ git rev-list --cherry-pick master..refs/pull/1112/head\n\n> I think that's probably the best answer to your \"unmerged\" question,\n> too. Ask the API which PRs are unmerged, and then do whatever git-level\n> analysis you want based on that.\n\nRight, that makes sense. Thanks again!\n"},{"id":"309801","messageId":"20170119222407.7y55did5hft55s27@sigill.intra.peff.net","threadId":"44916","inReplyTo":"9f59c0d7-73d3-1b4c-65ca-700d6e1f4f23@nottheoilrig.com","subject":"Re: grep open pull requests","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2017-01-19T22:24:07Z","receivedAt":"2017-01-19T22:24:34Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jan 19, 2017 at 03:12:53PM -0700, Jack Bates wrote:\n\n> Cool, thanks for all your help! \"git log --cherry-pick\" works quite well.\n> One thing: I expected the following to be equivalent, but found that they're\n> not. Is that by accident or design?\n> \n>   $ git rev-list --cherry-pick --right-only master...refs/pull/1112/head\n>   $ git rev-list --cherry-pick master..refs/pull/1112/head\n\nIt's by design. The \"left\" and \"right\" notions are defined only for a\nthree-dot symmetric difference.\n\nIn the first command you've asked git to look at commits on _both_\nmaster and the PR, down to their merge base. It marks the tips with a\n\"left\" and \"right\" bit, and then those bits propagate down.\n\nIn the second command, you've only asked for the PR commits, and there\nis no left/right bit at all. So --cherry-pick is doing nothing, as it\nhas no \"left\" commits to compare to.\n\n-Peff\n"}]}