gh はGitHub公式のコマンドラインツール。Go製の単一バイナリで、PRの作成・issueの整理・CIワークフローの監視・REST/GraphQL APIの呼び出しまで、ブラウザを開かずにすべてターミナルで完結できる。キラー機能は3つ — gh pr create(ブランチからPRオープンまで1コマンド)、gh api --paginate --jq(REST/GraphQL を auth と pagination込みでシェルパイプに直結)、gh run watch(CIのライブ監視。失敗時に非ゼロで終了するのでスクリプトに組み込める)。インストール後 gh auth login を一度実行すれば、その後のGitHub操作はすべてターミナルの中に閉じる。
git push で git の仕事は終わる。けれどその後の操作 — PRのオープン、レビュアー指名、レビューコメントの読み取り、CIマトリクスが緑になるまでの待機、マージ、ブランチ削除、リリース作成 — これまではすべてブラウザに切り替えて、3つくらいメニューをクリックして、毎回フローを断ち切っていた。このコストは目に見えにくいが莫大で、2026年の SmartScope レポート は開発者が1日平均20分をPR関連のブラウザ操作に費やしていると推計している。その大半は機械的なクリックで、gh の1コマンドで置き換えられる。
GitHub CLI はGitHub自身が出した答えだ。実装は Go — このCLIシリーズで唯一の非Rust製ツールだが、それは正解の選択。Goは標準ライブラリにファーストクラスのHTTPクライアントがあり、すべてのプラットフォームで単一バイナリにクロスコンパイルでき、GitHubの内部SDKも流用できる。結果として gh は、まるで git の隣に最初から存在していたかのような使い心地になっている。本記事は日常的に使うパターン — PRワークフロー、issueトリアージ、gh api スクリプティング、CI監視 — を実用レシピとしてまとめる。
なぜ gh CLI がターミナルとGitHubを橋渡しするのか
git は2005年に完成して、今でもその仕事を完璧にこなしている。けれどその上に乗っかったプラットフォーム層 — pull request、コードレビュー、issueトラッキング、GitHub Actions — は、10年後に企業がボルトオンしたもので、長らくWebサイトでしか操作できなかった。ここに gh がはまる。
gh が与えてくれるレバレッジは、5種類のコンテキストスイッチを消すことから来る:
- PR作成:
ghがない世界では、ブランチをpush → リモートが出力したURLをコピー → ブラウザに貼る → "compare & pull request" をクリック → フォーム入力 → submit、というのが定型。gh pr create --fillならコミットメッセージから自動でtitleとbodyを埋めてくれて、PRオープンまで0.5秒で済む。 - レビューコメントの読み取り: GitHubのデフォルトUIはインラインコメントをタブとタイムラインの奥に埋めてしまう。
gh pr view 123 --commentsなら全コメントをスレッド化してターミナルに吐き出してくれて、grepもスクロールもコピーも自由。 - CIステータスの確認:
gh pr checksでPRに紐づく全ワークフローの状態を表示でき、gh run watchは実行中のワークフローに張り付いて--exit-statusフラグで&& notify-send doneのようにチェーンできる。 - APIスクリプティング: 組織横断で全 issue を集めたい、全リリースタグを取りたい、
bugラベルが付いた全PRを抽出したい — そういうときgh api --paginate --jqがcurl + jq + 認証トークン + ページネーションを1コマンドでこなしてくれる。認証はgh auth loginで一度済ませるだけ。 - カスタムワークフロー:
gh extension installでコミュニティ拡張を組み込めるし、自作も簡単。gh dashのTUIダッシュボード、gh poiのブランチクリーンアップ、gh-pr-awaitのPR変化ポーリングなど、便利な拡張が揃っている。
これらを curl と手作りのOAuthフローで一から書いたら、それぞれ半日仕事になる。gh はそれを全部すでに配線済みで配ってくれる。
gh のインストールと認証
インストールはパッケージ1つ + 対話ログイン1回。公式の インストールページ に全プラットフォームのコマンドが載っている。短くまとめると以下。
# winget (Windows 11 標準)
winget install GitHub.cli
# Scoop
scoop install gh
# Chocolatey
choco install gh
インストール後、gh --version で確認したら、認証を1回だけ走らせる:
gh auth login
対話プロンプトが立ち上がる。GitHub.com か GitHub Enterprise ホストかを選び、git操作にHTTPSとSSHのどちらを使うか選び、Login with a web browser を選択。gh が8文字のデバイスコードを表示してブラウザを開くので、そのコードを貼って OAuth スコープを承認すれば、トークンがOSのキーチェーン(macOS Keychain、Windows Credential Manager、Linux なら libsecret)に保存される。
認証後、2つのコマンドで動作確認:
gh auth status
gh api user --jq '.login'
1つ目はログイン中のホストとトークンが持つスコープを表示する。2つ目はGitHub APIに自分として接続してユーザー名を表示する。両方動けば、本記事の他のすべてのコマンドも動く。
PRワークフロー: gh pr create から gh pr merge まで
ここがインストール代を回収するセクション。日常のPRループ全体が、おおよそ6コマンドで収まる。
PRを作る
git push -u origin my-branch した後、最小の作成コマンドはこれ:
gh pr create --fill
--fill は最新のコミットメッセージからtitleとbodyを自動で埋める。明示的に指定したい場合:
gh pr create \
--title "delta のホバー状態のリグレッションを修正" \
--body "Closes #142. ホバーハンドラが2回発火していた。" \
--base main \
--reviewer omitsu-dev,@studio-mitsu/reviewers \
--label bug,frontend \
--assignee @me \
--draft
公式 example 集 には他の細かいフラグ(--project, --milestone, --template)も載っている。覚えておきたいパターンは1つ — --reviewer は同じフラグの中で個人と @org/team 形式のチームスラッグを混ぜて指定できる。1行で個人とチーム両方にレビュー依頼が飛ぶ。
ブランチがまだpushされていない場合、gh pr create がpushを代行するか聞いてくる。yesと答えれば同じステップでpushとPRオープンが両方完了する。
PRを見る・読む
gh pr view 142 # ターミナルにMarkdownサマリ
gh pr view 142 --comments # 全レビューコメントもスレッド化して表示
gh pr view 142 --web # リッチUIが必要ならブラウザで開く
gh pr diff 142 # プレーンなunified diff
gh pr diff 142 | delta # delta にパイプしてsyntax highlight + side-by-side
最後の行が、前回 delta の記事 を書いた理由そのもの。gh pr diff | delta はターミナルで再現できる「GitHub Files Changedタブ」の最良近似で、しかもブラウザより速い。
レビュー・承認
gh pr checkout 142 # PRブランチをローカルにチェックアウト(fork対応)
gh pr review 142 --approve --body "LGTM, ship it"
gh pr review 142 --request-changes --body "インラインで指摘した箇所を確認してほしい"
gh pr review 142 --comment --body "下に質問あり"
gh pr checkout は覚えておく価値がある。クロスリポジトリのfork(user:branch)を解決して、後続の git push が破綻しないようにupstream tracking branch も自動で設定してくれる。
マージとクリーンアップ
gh pr merge 142 --squash --delete-branch
gh pr merge 142 --merge --auto # auto-merge を有効化: 必須チェックの通過を待つ
gh pr merge 142 --rebase --delete-branch
--auto フラグは働き方を変える。draft PRに対して --auto を有効化 → ready for review にマーク → 必須チェックがすべて通った瞬間に gh が自動でマージ。CIをずっと見張る必要がなくなる。
issue ワークフロー: 検索・トリアージ・コメント
issueはPRより地味だが、gh issue は一括メンテナンスを高速化してくれる。issue検索構文 はWeb UIと同じなので、覚え直しは不要。
# 自分にアサインされたopen issueを一覧
gh issue list --assignee @me --state open
# ラベル + 著者で検索
gh issue list --search "is:open label:bug author:omitsu-dev"
# サクッと作る
gh issue create --title "モバイルSafariでホバー状態が壊れる" \
--body "iOS 18.3 で再現。スクショあり。" \
--label bug,mobile
# 読む
gh issue view 142 --comments
# コメント・クローズ・再オープン
gh issue comment 142 --body "Fixed in #198."
gh issue close 142 --reason completed
gh issue reopen 142
ここで真価を発揮するのが パイプによる一括操作。たとえば wontfix ラベルが付いていて半年以上更新のないissueを全部閉じたいとする:
gh issue list \
--label wontfix \
--search "updated:<2025-10-10" \
--json number \
--jq '.[].number' |
xargs -I{} gh issue close {} --reason "not planned"
注目ポイントは2つ。1つ目は --json フラグ — 人間向けのテーブルではなく構造化されたJSONを返してくれる。これが gh を「便利UI」から「スクリプティングツール」に格上げする魔法のフラグ。2つ目は結果を xargs にパイプしている点。CLI地図 で紹介した使い方そのままだ。この瞬間から、gh は単なる便利機能ではなく 力の増幅器 になる。
gh api: jq とページネーションでGitHubをスクリプティング
gh api は gh を「生産性ツール」から「自動化基盤」に変える機能。curl + 認証 + ページネーション + JSONフィルタを1コマンドにまとめたもので、認証は既存の gh auth トークンが使われる。
基本形:
gh api repos/cli/cli/releases/latest --jq '.tag_name'
# v2.89.0
これがすべて。gh api PATH は https://api.github.com/PATH への GET で、トークンは自動で付く。--jq はレスポンスを jq に通した結果を出力する。ヘッダ・ページネーション・認証 — gh が全部面倒を見てくれる。
フィルタとテンプレート
# あるリポの直近10リリースをタグ + 日付で
gh api repos/cli/cli/releases \
--jq '.[0:10] | .[] | "\(.tag_name)\t\(.published_at)"'
# 同じデータをjqではなくGoテンプレートで
gh api repos/cli/cli/releases \
-t '{{range .}}{{.tag_name}}{{"\t"}}{{.published_at}}{{"\n"}}{{end}}'
-t フラグは隠れた便利機能。jq が入っていない環境(軽量コンテナなど)でもGoテンプレートで大半のことができる。
ページネーション
GitHubはほとんどのlistエンドポイントを30件単位でページネーションする。全部欲しければ:
gh api --paginate repos/cli/cli/issues --jq '.[].number'
--paginate は Link: rel="next" ヘッダを追跡してページがなくなるまで取得する。1つだけ知っておくべき制約: issue #10459 のとおり、--paginate --slurp --jq の3つは現状組み合わせられない。--paginate --jq(ページごとにjq適用)か、--paginate --slurp(全ページを1つのJSON配列にまとめてから別途jq)のどちらかを使う。
POST, PATCH, DELETE
# issueにコメントを追加
gh api repos/omitsu-dev/32blog/issues/142/comments \
-f body='Fixed in 0a1b2c3.'
# ラベルを追加
gh api repos/omitsu-dev/32blog/issues/142/labels \
-f labels[]=bug -f labels[]=frontend
# リリースをDELETE
gh api -X DELETE repos/omitsu-dev/32blog/releases/12345
-f は静的な文字列フィールド、-F は型付きフィールド(数値・真偽値・ファイル内容を @path で送れる)。@- 構文ならstdinからも読めるので、cat body.md | gh api ... -F body=@- のような芸当も簡単。
GraphQL
同じコマンドがGraphQLエンドポイントも喋れる。GitHub公式ブログのGraphQL解説 はブックマーク推奨。
gh api graphql -F owner=cli -F name=cli -f query='
query($owner:String!, $name:String!) {
repository(owner:$owner, name:$name) {
stargazerCount
defaultBranchRef { name }
}
}
' --jq '.data.repository'
GraphQLでページネーションするには pageInfo { hasNextPage, endCursor } 句と魔法の変数 $endCursor: String が必要。テンプレート全文は gh api マニュアル を参照。これらが揃えば --paginate --slurp で全ページを自動巡回してくれる。
gh run watch・拡張・エイリアス
最後の層は、gh を自分専用のターミナルダッシュボードに育てる部分。
CIを監視する
gh run list # 直近のワークフロー実行
gh run view 1234567890 # 1つのrunをjob/step単位で表示
gh run view 1234567890 --log # 全ログをストリーム
gh run view --log-failed # 失敗したstepだけ
gh run watch # 進行中のrunのライブステータス
gh run watch --exit-status # 失敗時に非ゼロで終了(CI向け)
gh run rerun 1234567890 --failed # 失敗jobだけ再実行
gh pr checks # 現PRの全チェック状態
gh run watch --exit-status がスクリプティングの要石。gh run watch マニュアル によれば、デフォルトで3秒間隔でポーリング(-i で変更可能)し、ワークフローが失敗した場合に非ゼロで終了する。だから何にでもチェーンできる:
git push && gh run watch --exit-status && notify-send "ビルド成功"
通知が飛ぶのは「ビルドが本当に通ったとき」であって、「自分がブラウザタブをチェックすることを思い出したとき」ではない。
拡張
gh extension install dlvhdr/gh-dash # PRとissueのTUIダッシュボード
gh extension install yusukebe/gh-markdown-preview
gh extension list
gh extension upgrade --all
gh extension remove gh-dash
拡張マニュアル には自作する方法も書いてある。拡張といっても、要するに $PATH 上にある gh-foo という名前の実行可能ファイル — 1行のbashスクリプトでも立派な拡張になる。
エイリアス
gh alias set prs 'pr list --author @me'
gh alias set bugs 'issue list --label bug --state open'
gh alias set ship 'pr merge --auto --squash --delete-branch'
gh alias list
エイリアスは ~/.config/gh/config.yml に保存される単純な文字列置換。複数ステップや条件分岐が必要ならシェル側で関数を書いたほうがよい — シェルエイリアス記事 を参照。
gh-copilot 拡張の終了について
2026年に「gh copilot suggest の使い方」を検索してここに来た読者も多いはず。残念ながら答えは変わった: gh-copilot 拡張は2025年10月25日に retire された。後継は別バイナリの GitHub Copilot CLI(コマンド名 copilot、2026-04-09時点で v1.0.22)で、もはや gh の拡張ではなく、brew install copilot-cli または npm install -g @github/copilot でインストールする独立したエージェント型アシスタントになっている。retire 前に拡張をインストール済みのユーザーに限り、旧 ghcs / ghce エイリアスはまだ動くが、新規導入は新しい standalone ツールを使うこと。
FAQ
Q. gh と git は同じもの?
違う。git はローカルのコミットとブランチを管理するツールで、gh はGitHub上で動く部分 — PR・issue・リリース・ワークフロー実行・API — を管理する。両者は補完関係。gh は git のコマンドを置き換えるのではなく、その上にGitHub固有の層を足す。
Q. gh は GitHub Enterprise Server で使える?
使える。gh auth login に --hostname your-ghes.example.com を渡せば、その後のすべてのコマンドがそのホストを向く。複数ホストに同時ログインできて、gh auth switch で切り替えられる。
Q. スクリプトからdraft PRを作れる?
作れる。gh pr create --draft --fill の1行で完結。draftをready for reviewに昇格させたいときは gh pr ready 142。
Q. 自分が今までに開いた全PRを全リポジトリ横断で見たい
gh search prs --author @me --state all --limit 1000。gh search ファミリはGitHubのグローバル検索を叩くので、リポジトリ横断のクエリにはこちらを使う。リポジトリごとに gh pr list をループするより圧倒的に速い。
Q. gh api の出力をシェル変数に入れたい
コマンド置換と --jq で必要なフィールドだけ抜く:
tag=$(gh api repos/cli/cli/releases/latest --jq .tag_name)。再利用するときは必ずクォートで囲むこと。
Q. gh run watch と gh pr checks の違いは?
gh pr checks は現PRのワークフロー状態を一発取得するスナップショット。gh run watch は1つのワークフロー実行が終わるまでブロックして待つライブテール — しかも失敗時に非ゼロで終了するのでスクリプト化できる。
Q. gh がGoで書かれているのはGitHubがGoのショップだから?
だいたい正解。GitHubの内部サービスはRubyとGoの混在だが、CLIに関してはGoを意図的に選んでいる。理由は単一スタティックバイナリをプラットフォーム別に出せること、標準ライブラリにファーストクラスのHTTPクライアントがあることなど。同じトレードオフが モダンCLIツールの大半 がRubyやPythonではなくRustかGoを選ぶ理由でもある。
Q. gh copilot suggest はまだ動く?
2025年10月25日より前に gh-copilot 拡張をインストールしていてアンインストールしていなければ動く。それ以外の場合は新規インストール自体がブロックされる。代わりに standalone の GitHub Copilot CLI を使うこと — これが今後サポートされる正規ルート。
まとめ
gh は git の片割れだ。分裂は歴史的な事情によるもの(GitはGitHubより3年古く、pull requestより6年古い)だが、実用上の結末は同じ — 2026年の多くの開発者にとって、日常のGitHub作業の半分が誰も望んでいないブラウザタブの中にある。gh はそのブラウザタブを、もとから他のすべてが動いているターミナルへ折りたたみ直してくれる。
インストール代を回収する4つのコマンド:
gh pr create --fill— 直前のコミットからキー1つでPRを開くgh pr diff | delta— diffをコードレビューツールのようにターミナルで読むgh api --paginate --jq— GitHubをローカルDBのようにスクリプティングgh run watch --exit-status— スクリプトやシェルループの中でCIをブロック待機
gh を delta(diff表示)、bat(PRチェックアウト後のファイル閲覧)、ripgrep(クローン済みリポ内の全文検索)、fzf(PR番号のインタラクティブ選択)と組み合わせれば、日常のGitHub作業がすべて1つのターミナルウィンドウに収まる。これが モダンCLIシリーズ のゴールであり、gh はプラットフォーム層全体をワークフローの残りに結びつける最後のピースだ。