【Git・GitHub操作ガイド】第9章 GitHub CLI (gh) の使い方入門!開発効率を上げる便利コマンド&自動化スクリプト集

はじめに:面倒な「行き来」、していませんか?

「やっとコーディングに集中できると思ったら、レビュー依頼の通知。ブラウザでPRを開き、ブランチ名を確認してコピー、ターミナルに戻って git checkout を貼り付け…。やっとの思いでレビューを始めた頃には、もう集中力は途切れ途切れにに。。。」

こんな風に、GitHubの操作のためにブラウザとターミナルを行き来することに、小さなストレスを感じたことはありませんか?その「小さなストレス」、積もり積もって集中力を奪う厄介な敵です。

GitHub CLI導入前後の作業風景の比較

この作業の切り替え(コンテキストスイッチ)は、集中力を削ぎ、煩わしさを生む原因になります。

(注: コンテキストスイッチとは、思考や作業の対象を切り替えることです。プログラミングのような集中力が必要な作業では、少しの中断が大きな効率低下につながることがあります。)

この記事を読めば、あなたも…

ghコマンドでPRやIssueをターミナルから操作できるようになる
✅ 面倒な定型作業を自動化する「自分だけのコマンド」を作れるようになる
✅ ブラウザとターミナルの行き来が減り、開発に集中できる時間が増える


この記事の対象読者

  • プログラミング学習を始めたばかりの方
  • GitやGitHubの基本操作に慣れてきた方
  • 黒い画面(ターミナル)での作業が好きな方
  • 開発の効率を少しでも上げたいと思っている方

目次


GitHub CLI(gh)とは?

今回紹介するGitHub CLI(gh は、コマンドライン(ターミナル)からGitHubのほぼすべての機能を操作できるようにする公式ツールです。

これを導入することで、作業中のターミナルやIDEから離れることなく、開発ワークフロー全体をスムーズに実行できるようになります。

ghの基本的な使い方は、gh <操作対象> <実行内容> という直感的な形式になっています。

  • Issueを一覧したい → gh issue list
  • PRを作成したい → gh pr create
  • リポジトリをブラウザで開きたい → gh repo view --web

このように、GitHubのWebサイトで日常的に行っている操作の多くが、コマンドに置き換えることができます。


準備:ghを使えるようにしよう

この記事で紹介するコマンドを使うには、GitHub CLIのインストールと認証が必要です。

1. インストール

お使いのOSに合わせて、以下のコマンドでインストールできます。

  • macOS (Homebrew): brew install gh

2. 認証

インストール後、ターミナルで以下のコマンドを実行します。
gh auth login
いくつか質問が表示されますが、基本的には推奨設定(デフォルト)のままEnterキーを押していけば大丈夫です。途中でブラウザが開き、GitHubアカウントへのアクセス許可を求められたら、許可してください。

これで準備は完了です!

GitHub CLIのインストールの詳細は、以下の記事で詳細に解説していますので、是非ご覧ください。


まずはこれ!現場で使えるgh基本コマンド5選

1. リポジトリのクローンと作成 (gh repo create, gh repo clone)

概要:

git cloneの高機能版です。単にクローンするだけでなく、フォーク元のリポジトリをupstreamとして自動で登録してくれるなど、賢く動作します。また、ターミナルから直接GitHub上に新しいリポジトリを作成することもできます。

利用シーン:

  • 新しいプロジェクトを始めるにあたり、ローカルディレクトリを元にGitHubリポジトリを作成したい。
  • オープンソースプロジェクトに参加するため、リポジトリをフォークしてクローンしたい。

実行手順:

ローカルディレクトリを元にGitHubリポジトリを作成

# カレントディレクトリを元に、'my-new-project' という名前のリポジトリをGitHub上に作成
gh repo create my-new-project --public --source=. --remote=origin

【コマンド解説】

  • --public: 公開リポジトリとして作成します。(非公開にしたい場合は --private を使います)
  • --source=.: 今いるディレクトリ(カレントディレクトリ)にあるファイルを元に作成します。
  • --remote=origin: ローカルリポジトリのリモート接続先として origin という名前を設定します。

OSSリポジトリをフォークしてクローン

# 'owner/repo' をクローンします
# 対話形式で「このリポジトリをフォークしますか?」と聞いてくれます
gh repo clone owner/repo

# クローン後、'upstream' という名前でフォーク元のリポジトリが自動登録されます
# これにより、本家の変更を取り込むのが簡単になります!
$ git remote -v
# origin  https://github.com/YOUR_NAME/repo.git (fetch)
# origin  https://github.com/YOUR_NAME/repo.git (push)
# upstream        https://github.com/owner/repo.git (fetch)
# upstream        https://github.com/owner/repo.git (push)

補足:originupstream って何?

オープンソース開発などで fork を使うワークフローでは、リモートリポジトリが2つ登場します。gh repo clone はこの設定を自動で行ってくれる便利なコマンドです。それぞれの役割を理解しておきましょう。

  • upstream: 「上流」という意味で、フォーク元となった大本のリポジトリを指します。通常、他の開発者や組織が管理しており、私たちは直接変更を加える権限(push権限)を持ちません。プロジェクトの最新の変更は、ここから取得します。
  • origin: 「起源」という意味ですが、この文脈では自分自身がフォークして作成したリポジトリ(自分のGitHubアカウント上にあるコピー)を指します。これには自由にpushできます。変更作業はここに対して行い、最終的に upstream へPull Requestを送ります。

【関係性のイメージ図】

この3つのリポジトリの関係は、よく「図書館」に例えられます。

  1. upstream (大図書館): プロジェクトの原本が保管されている大きな図書館。誰もが読むこと(pull/fetch)はできるが、書き込むことはできません。
  2. origin (自分の書斎の本棚): 大図書館から借りてきた本(リポジトリ)をコピーして置いておく、自分の家の本棚。自由に書き込んだり(push)、付箋を貼ったりできます。
  3. ローカル (机の上): 実際に作業をする机の上。本棚(origin)から本を持ってきて(clone/pull)、編集作業を行う場所です。
リポジトリの関係イメージ

さらに、ブランチレベルでの変更の流れを可視化すると以下のようになります。

リポジトリのブランチレベルの関係イメージ

【一般的なワークフロー】

  1. fork: まず、GitHub上で upstream リポジトリを自分のアカウントにフォークし、origin を作ります。
  2. clone: 次に、gh repo clone を使って自分の origin リポジトリをローカルPCにクローンします。このとき、ghが自動で upstream も登録してくれます。
  3. fetch & merge: 作業を始める前に、upstream の最新の変更を git fetch upstream で取得し、git merge upstream/main などで自分のブランチに取り込みます。(本が改訂されたので、最新版に差し替えるイメージです)
  4. push: 自分のPCで加えた変更を、git push origin my-feature-branch のように origin にプッシュします。
  5. Pull Request: 最後に、GitHub上で origin の変更を upstream に取り込んでもらうよう、Pull Requestを作成します。

gh repo clone はこのステップ2をまとめて行ってくれるため、OSSへの参加やチーム開発のスタートアップがスムーズになります。


2. Pull Requestの一覧とチェックアウト (gh pr list, gh pr checkout)

概要:

レビュー作業を効率化するコマンドです。自分にレビュー依頼が来ているPRを一覧したり、特定のPRをコマンド一つでローカルに持ってきて動作確認したりできます。

利用シーン:

  • 「今日のレビュー対象は何かな?」と確認したい。
  • レビューするために、PRのコードをローカルで動かしてみたい。

実行手順:

# 現在オープンなPRを一覧表示
gh pr list

# 自分にレビューが依頼されているPRを一覧表示
gh pr list --search "is:open review-requested:@me"

# PR番号123のブランチをローカルに切り替える(ブランチ名などを覚える必要がない!)
gh pr checkout 123

コマンド例:

hogehoge@mac hello-world % gh pr list

Showing 1 of 1 open pull request in hogehoge/hello-world

ID   TITLE              BRANCH            CREATED AT            
#11  Update index.html  feature/d-branch  less than a minute ago
hogehoge@mac hello-world 
hogehoge@mac hello-world 

コマンド例:

hogehoge@mac hello-world % gh pr list --search "is:open review-requested:@me"

Showing 1 of 1 pull request in hogehoge/hello-world that matches your search

ID   TITLE              BRANCH            CREATED AT         
#11  Update index.html  feature/d-branch  about 5 minutes ago

コマンド例:

hogehoge@mac hello-world % gh pr checkout 10
Enter passphrase for key '/Users/hogehoge/.ssh/id_ed25519'
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (3/3), 931 bytes | 103.00 KiB/s, done.
From github.com:hogehoge/hello-world
 * [new branch]      feature/d-branch -> origin/feature/d-branch
branch 'feature/d-branch' set up to track 'origin/feature/d-branch'.
Switched to a new branch 'feature/d-branch'
hogehoge@mac hello-world % git status
On branch feature/d-branch
Your branch is up to date with 'origin/feature/d-branch'.

nothing to commit, working tree clean
hogehoge@mac hello-world %

3. Issueの検索 (gh search issues)

概要:

Web UIと同じように、ラベルや担当者などでIssueを柔軟に検索できます。

利用シーン:

  • 自分が担当しているバグのIssueを条件を指定して確認したい。

コマンド例:

# キーワード "readme" と "typo" の両方に一致するIssueを検索
$ gh search issues readme typo

# フレーズ "broken feature" に一致するIssueを検索
$ gh search issues "broken feature"

# cli オーガニゼーション内のIssueとプルリクエストを検索
$ gh search issues --include-prs --owner=cli

# 自分に割り当てられているオープンなIssueを検索
$ gh search issues --assignee=@me --state=open

# コメントが100件より多いIssueを検索
$ gh search issues --comments=">100"

# "bug" ラベルを含まないIssueを検索
$ gh search issues -- -label:bug

# アーカイブされていないリポジトリからのみIssueを検索(デフォルトは全リポジトリ)
$ gh search issues --owner github --archived=false

コマンド実行例:

# --state=open(未解決のIssue)かつ --label=bug(bugラベル付き)かつ
# --assignee=@me(自分が担当者)のIssueを検索
# このように、GitHubのWebサイトで使う検索クエリをそのまま渡せます
hogehoge@mac hello-world % gh search issues --assignee=@me --state=open --label=bug

Showing 1 of 1 issues

REPO                        ID   TITLE                             LABELS  UPDATED            
hogehoge/hello-world  #12  index.htmlのタイトルが誤っている  bug     about 5 minutes ago
hogehoge@mac hello-world %

4. ワークフローの実行 (gh workflow run)

概要:

workflow_dispatchトリガーを持つGitHub Actionsのワークフローを、手動で実行します。

利用シーン:

  • ステージング環境へのデプロイ用ワークフローを、任意のタイミングで実行したい。

実行手順:

# 'deploy.yml' という名前のワークフローを 'main' ブランチで実行
gh workflow run deploy.yml --ref main

実行中のログをリアルタイムで見たい場合は gh run watch が便利です。

コマンド実行例:

hogehoge@mac hello-world % gh workflow run main.yml --ref feature/d-branch
 Created workflow_dispatch event for main.yml at **feature/d-branch**

To see runs for this workflow, try: **gh run list --workflow="main.yml"**

hogehoge@mac hello-world % gh run watch
found no in progress runs to watch

hogehoge@mac hello-world % gh workflow run main.yml --ref feature/d-branch
 Created workflow_dispatch event for main.yml at **feature/d-branch**

To see runs for this workflow, try: **gh run list --workflow="main.yml"**
hogehoge@mac hello-world % gh run watch                                   
**?** **Select a workflow run** * Hello World Action, Hello World Action [feature/d-branch] 2s ago
 **feature/d-branch** Hello World Action orcus-s13i-tbp/hello-world#11 · 778331
Triggered via workflow_dispatch less than a minute ago

**JOBS**
 **say-hello** in 4s (ID 50514)
   Set up job
   Say Hello
   Check Runner OS
   Complete job

 Run **Hello World Action** (778331) completed with 'success'
hogehoge@mac hello-world %

5. エイリアスの設定 (gh alias set, gh alias delete)

概要:

よく使うけれど少し長いコマンドに、自分だけの短い別名(エイリアス)を付ける機能です。

利用シーン:

  • gh pr list --search "is:open review-requested:@me" は毎回入力するのが大変なので、gh pr-review というコマンドで実行したい。

実行手順:

# 'prr' というエイリアス(別名)を設定します
# '!' を先頭につけることで、シェルコマンドではなくghコマンド自身を実行するよう指定します
gh alias set prr '!gh pr list --search "is:open review-requested:@me"'

# これで次回から 'gh prr' を実行するだけでよくなります
gh prr

コマンド実行例:

hogehoge@mac hello-world % gh alias set prr '!gh pr list --search "is:open review-requested:@me"'
- Creating alias for **prr**: **!gh pr list --search "is:open review-requested:@me"**
 Added alias **prr**

hogehoge@mac hello-world % gh prr

Showing 1 of 1 pull request in hogehoge/hello-world that matches your search

ID   TITLE              BRANCH            CREATED AT          
#11  Update index.html  feature/d-branch  about 52 minutes ago
hogehoge@mac hello-world %

補足:エイリアスの確認と解除

設定したエイリアスは、gh alias list コマンドでいつでも確認できます。

実行手順:

# 設定されているエイリアスの一覧を表示
gh alias list

コマンド実行例:

# エイリアスの一覧を表示
hogehoge@mac hello-world % gh alias list
co: pr checkout
prr: '!gh pr list --search "is:open review-requested:@me"'
hogehoge@mac hello-world %

不要になったエイリアスは gh alias delete コマンドで簡単に削除できます。

実行手順:

# エイリアスを削除
gh alias delete prr

コマンド実行例:

# 'prr' 
hogehoge@mac hello-world % gh alias delete prr
 Deleted alias prr; was !gh pr list --search "is:open review-requested:@me"

# 削除されたか確認
hogehoge@mac hello-world % gh alias list      
co: pr checkout
hogehoge@mac hello-world %

応用編:シェルスクリプトで「自分だけのコマンド」を作ろう

ghコマンドの真価は、シェルの設定ファイル(.bashrc.zshrcなど)に「関数」や「エイリアス」を追記し、自分だけのオリジナルコマンドとして使うことで発揮されます。

ここでは、実践的な4つの便利ケースを照会します。


ケース1: 次にレビューすべきPRを瞬時に開く

「さて、次にレビューするPRはどれだっけ?」と思った瞬間に、対象のPRページをブラウザで開く関数です。

# 'review'
function review() {
    # PRの「番号」を取得
    local pr_number
    pr_number=$(gh pr list --search "is:open review-requested:@me" --limit 1 --json number --jq '.[0].number')

    if [ -n "$pr_number" ]; then
        echo "レビュー対象のPR #${pr_number} を開きます..."
        # gh pr view <番号> --web を使ってブラウザで開く
        gh pr view "$pr_number" --web
    else
        echo "レビュー待ちのPRはありませんでした!素晴らしい!✨"
    fi
}

これを設定しておけば、ターミナルで review と打つだけで、次にレビューすべきPRがブラウザで開きます。集中を妨げません。


ケース2: お掃除も一瞬!マージ済みブランチをまとめて削除

作業が終わったブランチがローカルにどんどん溜まって、git branch の一覧が見づらくなっていませんか?この関数を使えば、GitHub上でマージ済みのローカルブランチを安全に一括削除できます。

# 'git-clean' 
function git-clean() {
    # 1. リポジトリのデフォルトブランチ名を動的に取得する
    local default_branch
    default_branch=$(gh repo view --json defaultBranchRef --jq .defaultBranchRef.name)

    if [ -z "$default_branch" ]; then
        echo "エラー: デフォルトブランチを取得できませんでした。"
        return 1
    fi

    # 2. 安全なデフォルトブランチへの移動を試み、失敗したら処理を中断する
    echo "デフォルトブランチ '${default_branch}' に切り替えます..."
    git switch "$default_branch" || return 1

    # リモートの最新の状態(どのブランチがマージされたか)を取得します
    echo "リモートの最新情報を取得します..."
    git fetch --prune

    echo "以下のマージ済みローカルブランチを削除します..."
    # `gh pr list` でマージ済みのPRのブランチ名を取得し、
    # `grep` で保護したいブランチ(デフォルトブランチなど)を明示的に除外してから、
    # `xargs` を使って `git branch -d` コマンドに渡し、一つずつ削除します
    gh pr list --state merged --json headRefName --jq '.[].headRefName' \
        | grep -v -E "^(${default_branch}|master|develop)$" \
        | xargs -I {} git branch -d {}

    echo "お掃除完了です! ✨"
}

これで git-clean と打ち込むだけで、いつでもローカルリポジトリを綺麗な状態に保てます。

jq '.[].headRefName'の部分は、「JSON形式の結果の各要素(.[])から、defaultBranchRef.nameというキーの値だけを取り出す」という処理をしています。
git branch -d は、マージされていない変更が残っているブランチは安全のために削除しません。もし強制的に削除したい場合は -D オプションもありますが、まずは安全な -d から試すのがおすすめです。

ケース3: 面倒なPR作成をコマンド一発で

PR作成時に毎回ブラウザでベースブランチを選び、タイトルを書き、レビュアーを指定するのは面倒です。この関数は、PRのタイトルを渡すだけでシンプルなPRを作成します。

# 'cpr' (Create Pull Request) 
# 使い方: cpr "PRのタイトル"
function cpr() {
  # 現在のブランチをGitHubにプッシュします
  git push --set-upstream origin "$(git rev-parse --abbrev-ref HEAD)"

  # 定型的なPRを作成します
  # --base: ベースブランチ, --title: タイトル, --body: 本文, --reviewer: レビュアー
  gh pr create --base "main" --title "$1" --body "(ここにPRのテンプレートを記述)" --reviewer "my-org/reviewers"
}

$1 の部分には、cpr "すごい機能を追加" のように実行した際の最初の引数(”すごい機能を追加”)が入ります。
reviewer “my-org/reviewers”には、レビューアーとなるGithubアカウントを指定してください。

コマンド実行例:

# PRを作成
hogehoge@mac hello-world % cpr "test-pr"                      
Enter passphrase for key '/Users/hogehoge/.ssh/id_ed25519'
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 293 bytes | 293.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
remote: 
remote: Create a pull request for 'feature/e-branch' on GitHub by visiting:
remote:      https://github.com/hogehoge/hello-world/pull/new/feature/e-branch
remote: 
To github.com:hogehoge/hello-world.git
 * [new branch]      feature/e-branch -> feature/e-branch
branch 'feature/e-branch' set up to track 'origin/feature/e-branch'.

Creating pull request for feature/e-branch into main in hogehoge/hello-world

https://github.com/hogehoge/hello-world/pull/15
hogehoge@mac hello-world %

ケース4: 定型的なIssue報告をテンプレート化

関数を作るほどではないけれど、よく使うコマンドは「エイリアス(別名)」として登録すると便利です。これは、バグ報告用のIssueを簡単に作成するエイリアスの例です。

# 'bug-report' エイリアスを設定
# '!' を付けると、ghコマンドやシェルコマンドを直接実行できます
# $1, $2... はエイリアス実行時に渡される引数に置き換わります
gh alias set bug-report '!printf "## 概要\n%s\n\n## 再現手順\n1. \n2. \n\n## 環境\n- OS: \n- Browser: " "$2" | gh issue create --title "Bug: $1" --body-file - --label "bug"'

これを設定しておけば、以下のようにコマンドを実行するだけで、フォーマットに沿ったIssueが作成されます。

# 使い方
gh bug-report "ログイン画面でクラッシュする" "ユーザー名を入力するとアプリが落ちます"

$1には1番目の引数(この例では “ログイン画面でクラッシュする”)、$2には2番目の引数(”ユーザー名を入力するとアプリが落ちます”)が、それぞれ自動的に入ります。

チームでIssueのフォーマットを統一したい場合に使えます。


参考資料


まとめ:今日から始める「脱・面倒」なGitHub操作

ghは、日々の定型的な作業を自動化し、コーディングという本質的な作業に集中させてくれる「優秀なアシスタント」です。

この記事で紹介したコマンドは、その第一歩です。自分で、コマンドを調べて拡張してみてください。もっと、便利に快適な環境を作り出すことができます!
コマンドの自動化を一つずつ試していくことで、あなただけの「最強の時短術」が身についていきます!

さあ、あなたのMacを快適な開発環境にしましょう!!

SNSでもご購読できます。

コメントを残す

*