esm アジャイル事業部 開発者ブログ

永和システムマネジメント アジャイル事業部の開発者ブログです。

コミットハッシュからプルリクエストを特定する

Dolce Gustoを買ってからコーヒーを飲みすぎてしまっている wat-aro です。

開発をしていると書かれているコードの意図がわからないことがあります。
そういうときは git blame で該当コミットを確認しますが、コミットを確認しても意図がわからない場合にはプルリクエストを確認したくなります。
ここではプルリクエストを確認しやすくするためにコミットハッシュからプルリクエストを特定する方法を2点紹介します。

Merge pull request コミットから特定する

まずは コミットハッシュ プルリクエスト 検索 などで検索すると見つかるやり方*1です。
GitHub でプルリクエストをマージすると

Merge pull request #ISSUE_NUMBER from OWNER/BRANCH

のようなコミットメッセージがついたコミットが作成されます。

指定したコミットハッシュから HEAD までのログの中から最初に Merge pull request が含まれているコミットを見つければそこにプルリクエストの番号が入っています。

$ git config --global alias.searchpr '!f(){ git log --oneline --merges --reverse --ancestry-path $1..HEAD | grep "Merge pull request" | head -n 1 | cut -d" " -f 5;};f'
$ git searchpr b71abb3bb8cd
#33137

上記コマンドに GitHub CLI コマンドを合わせることでブラウザで開くこともできます。

$ git config --global alias.openpr '!f(){ git searchpr $1 | xargs -I ISSUE_NUMBER gh pr view ISSUE_NUMBER --web;};f'

しかし、この方法では Rebase and mergeSquash and merge には対応できません。

GitHub API から特定する

Rebase and merge Squash and merge の場合でも GitHub から検索することで該当プルリクエストを特定することができます。
GitHub CLI の gh pr view でコミットハッシュからプルリクエストを見ることができればよいのですが、残念ながらそのようなオプションはありません。

$ gh pr view --help
Display the title, body, and other information about a pull request.

Without an argument, the pull request that belongs to the current branch
is displayed.

With '--web', open the pull request in a web browser instead.


USAGE
  gh pr view [<number> | <url> | <branch>] [flags]

FLAGS
  -c, --comments   View pull request comments
  -w, --web        Open a pull request in the browser

INHERITED FLAGS
      --help                     Show help for command
  -R, --repo [HOST/]OWNER/REPO   Select another repository using the [HOST/]OWNER/REPO format

LEARN MORE
  Use 'gh <command> <subcommand> --help' for more information about a command.
  Read the manual at https://cli.github.com/manual

しかし GitHub CLI v0.10.0 から GitHub GraphQL API を叩けるようになりました。*2
これを使って、コミットハッシュを渡すと GitHub GraphQL API を叩いてプルリクエストの番号を返す alias を登録してみます。
取得した JSON からプルリクエストの番号を抽出するため jq が必要です。
以下は fish shell での記述になります。

$ gh alias set --shell searchpr "gh api graphql -F owner=':owner' -F repo=':repo' -F hash=\$1 -f query='
  query(\$repo:String!, \$owner:String!, \$hash:String) {
    repository(name: \$repo, owner: \$owner) {
      object(expression: \$hash) {
        ... on Commit {
          associatedPullRequests(first: 1) {
            edges {
              node {
                number
              }
            }
          }
        }
      }
    }
  }
' | jq .data.repository.object.associatedPullRequests.edges[0].node.number" 

zsh では ! もエスケープしなければいけません。

$ gh alias set --shell searchpr "gh api graphql -F owner=:owner -F repo=:repo -F hash=\$1 -f query='
  query(\$repo:String\!, \$owner:String\!, \$hash:String\!) {
    repository(name: \$repo, owner: \$owner) {
      object(expression: \$hash) {
        ... on Commit {
          associatedPullRequests(first: 1) {
            edges {
              node {
                number
              }
            }
          }
        }
      }
    }
  }
' | jq .data.repository.object.associatedPullRequests.edges[0].node.number"

bash では \! でエスケープした場合にそのまま \! という文字列になってしまうためこの書き方では実行できません。
この alias は次のように使うことが出来ます

$ gh searchpr b71abb3bb8cd
33137

後はプルリクエストを開く alias を登録するだけです。

$ gh alias set --shell openpr "gh searchpr \$1 | xargs -I ISSUE_NUMBER gh pr view ISSUE_NUMBER --web"
$ gh openpr b71abb3bb8cd

GitHub CLI は GitHub の OAuth access token を ~/.config/gh/hosts.yml に保持しているため、プライベートリポジトリでもこの方法でプルリクエストを特定することができます。

おわりに

GitHub CLI コマンドを使ってコミットハッシュからプルリクエストを特定する方法について紹介しました。
gh api コマンドを使うことで他にも色々なリソースを操作することができます。
GraphQL API の Explorer で query を作成して GitHub CLI を便利にしていきましょう。

この記事が開発の助けになれば幸いです。