GitHub Organizationで特定テンプレートから生成されたリポジトリ数をGitHub CLIとjqで調べてみた
GitHub Organization配下で、特定のテンプレートリポジトリから生成されたリポジトリが何件あるかを知りたいときがありました。
GitHubには、現時点(2026/8時点)でこれを直接確認するAPIがありません。
gh repo listとjqを組み合わせて、件数を調べてみました。
gh repo list --json templateRepositoryで取れる情報
gh repo listはOrganization配下のリポジトリ一覧を取得するコマンドです。リポジトリ名・説明・公開設定・更新日時をテーブル形式で表示します。
gh repo list <ORG>
Showing 30 of <TOTAL> repositories in @<ORG>
NAME DESCRIPTION INFO UPDATED
<ORG>/prj-xxxx private about 1 hour ago
<ORG>/prj-yyyy サンプルの説明文 private about 2 hours ago
(以下省略)
このテーブル表示にはtemplateRepositoryのような詳細情報は含まれません。--jsonオプションでフィールドを指定すると、必要な情報だけを構造化されたデータとして取得できます。
以下はtemplateRepositoryを指定した場合のコマンドと出力結果です。
gh repo list <ORG> --json name,templateRepository --limit 5
[
{
"name": "prj-bar",
"templateRepository": null
},
{
"name": "prj-foo",
"templateRepository": {
"id": "R_xxxxxxxxxxxxxxxxxxxxxx",
"name": "<TEMPLATE_REPO>",
"owner": {
"id": "MDxxxxxxxxxxxxxxxxxx",
"login": "<TEMPLATE_OWNER>"
}
}
}
]
ただし--helpのFLAGS一覧を見ても、「特定のテンプレートから生成されたリポジトリだけ」を絞り込むオプションはありません。
FLAGS
--archived Show only archived repositories
--fork Show only forks
-q, --jq expression Filter JSON output using a jq expression
--json fields Output JSON with the specified fields
-l, --language string Filter by primary coding language
-L, --limit int Maximum number of repositories to list (default 30)
--no-archived Omit archived repositories
--source Show only non-forks
-t, --template string Format JSON output using a Go template; see "gh help formatting"
--topic strings Filter by topic
--visibility string Filter by repository visibility: {public|private|internal}
--archivedや--visibilityのように属性で絞り込むフラグはありますが、templateRepositoryの値そのもので絞り込む手段はありません。
-t/--templateという名前のフラグもありますが、これは出力を整形するGoテンプレートの指定用で、テンプレートリポジトリの絞り込みとは無関係です。
そのため、Organization全体のリポジトリ一覧を--json templateRepository付きで取得したうえで、jqで対象のテンプレートと一致するものだけを抽出する構成にしました。
一覧取得とテンプレート判定自体は1コマンド(gh repo list)で済み、「特定のテンプレートに絞り込む」部分だけをjq側で担います。
スクリプトと実行結果
一覧取得とテンプレート判定の一連の処理をスクリプトにしてみました。
#!/usr/bin/env bash
#
# find-template-repos.sh
#
# GitHub organization 内で、指定したテンプレートリポジトリから作成された
# リポジトリの件数と一覧を表示します。
#
# 必要なもの:
# - GitHub CLI (gh) https://cli.github.com/
# - jq
# - `gh auth login` 済み、かつ対象 org のリポジトリを読める権限を持つトークン
#
# 使い方:
# ./find-template-repos.sh -o ORG -t TEMPLATE_OWNER/TEMPLATE_REPO [-l LIMIT]
#
# 例:
# ./find-template-repos.sh -o my-org -t my-org/service-template
#
set -euo pipefail
LIMIT=1000
usage() {
cat <<'EOF'
Usage: find-template-repos.sh -o ORG -t TEMPLATE_OWNER/TEMPLATE_REPO [-l LIMIT]
-o ORG GitHub organization のログイン名 (例: my-org)
-t TEMPLATE_OWNER/REPO テンプレートリポジトリのフルネーム (例: my-org/template-repo)
-l LIMIT org から取得するリポジトリ数の上限 (デフォルト: 1000)
-h このヘルプを表示
事前準備:
- GitHub CLI (gh) がインストール済みであること https://cli.github.com/
- jq がインストール済みであること
- `gh auth login` で認証済みであり、対象 org のリポジトリを読める権限があること
EOF
exit 1
}
while getopts "o:t:l:h" opt; do
case "$opt" in
o) ORG="$OPTARG" ;;
t) TEMPLATE="$OPTARG" ;;
l) LIMIT="$OPTARG" ;;
h|*) usage ;;
esac
done
if [[ -z "${ORG:-}" || -z "${TEMPLATE:-}" ]]; then
usage
fi
if ! command -v gh >/dev/null 2>&1; then
echo "エラー: GitHub CLI (gh) がインストールされていません。https://cli.github.com/ を参照してください。" >&2
exit 1
fi
if ! command -v jq >/dev/null 2>&1; then
echo "エラー: jq がインストールされていません。" >&2
exit 1
fi
if ! gh auth status >/dev/null 2>&1; then
echo "エラー: gh が認証されていません。'gh auth login' を実行してください。" >&2
exit 1
fi
echo "org '${ORG}' のリポジトリ一覧を取得中 (最大 ${LIMIT} 件)..." >&2
REPOS_JSON=$(gh repo list "$ORG" --limit "$LIMIT" \
--json name,templateRepository,createdAt,isArchived,visibility)
FETCHED=$(echo "$REPOS_JSON" | jq 'length')
if [[ "$FETCHED" -ge "$LIMIT" ]]; then
echo "警告: 取得件数が --limit (${LIMIT}) に達しています。超過分は取得できていない可能性があります。-l で上限を上げてください" >&2
fi
# 注意: --json templateRepository が返すオブジェクトには id/name/owner{login} しか
# 含まれず、nameWithOwner というキーは存在しない。
# .templateRepository.nameWithOwner のような直接比較は常に null になり、
# 該当リポジトリがあっても一致しないバグになるため、owner.login と name を
# 組み立てて比較する。
MATCHED_JSON=$(echo "$REPOS_JSON" | jq --arg tmpl "$TEMPLATE" '
[ .[] | select(
.templateRepository != null
and (.templateRepository.owner.login + "/" + .templateRepository.name) == $tmpl
) ]
| sort_by(.createdAt)
')
COUNT=$(echo "$MATCHED_JSON" | jq 'length')
echo ""
echo "=========================================="
echo "テンプレート : ${TEMPLATE}"
echo "対象組織 : ${ORG}"
echo "作成されたリポジトリ数: ${COUNT}"
echo "=========================================="
echo ""
if [[ "$COUNT" -eq 0 ]]; then
echo "該当するリポジトリは見つかりませんでした。"
echo "(テンプレート名の表記や、gh のアクセス権限をご確認ください)"
else
# 対象組織は上のヘッダーで表示済みなので、行ごとには name のみ表示する
# (URL が要る場合は https://github.com/${ORG}/リポジトリ名 で組み立てられる)
echo "$MATCHED_JSON" | jq -r '
.[] |
"- \(.name) [\(.visibility)]\(if .isArchived then " (archived)" else "" end)\n 作成日 : \(.createdAt)"
'
fi
実行結果は次のようになります(リポジトリ名・件数はサンプル値です)。
./find-template-repos.sh -o <ORG> -t <TEMPLATE_OWNER>/<TEMPLATE_REPO>
org '<ORG>' のリポジトリ一覧を取得中 (最大 1000 件)...
==========================================
テンプレート : <TEMPLATE_OWNER>/<TEMPLATE_REPO>
対象組織 : <ORG>
作成されたリポジトリ数: 15
==========================================
- prj-xxxx [PRIVATE]
作成日 : 2026-xx-xxTxx:xx:xxZ
(以下14件省略)
実機で確認しておきたいのが、--limitを省略した場合の動作です。gh repo listは--limitを省略するとデフォルトの30件しか返しません。--jsonを付けない表形式ではShowing 30 of <総数> repositories in @<ORG>のように件数が表示されますが、--jsonを付けるとこの表示は出ません。
エラーも警告もなく30件分のJSON配列だけが返ってくるので、--jsonで使う場合は--limitの指定を忘れると、対象Organizationの規模に関わらず30件だけ取得した結果になります。
スクリプトではこの問題を避けるため、--limitのデフォルト値を1000に設定し、常に明示的に渡すようにしています。
対象Organizationがそれ以上のリポジトリを抱えている場合は、-lに4000のような大きな値を指定すれば、その件数までを1コマンドでまとめて取得できます。ただし--limitを大きくするほど1回のリクエストで取得するデータ量が増えるので、そのぶん実行時間も伸びます。
検出できるのは「テンプレートから生成」機能を使った場合だけ
この方法には適用範囲があります。templateRepositoryは、GitHubの「Use this template」機能を使って生成されたリポジトリでのみ非nullになります。
テンプレートの中身をcloneして別リポジトリに手動でpushするような運用では検出できません。

GitHub公式コミュニティディスカッションでも同様の相談があり、特定のテンプレートから生成されたリポジトリを直接検索するAPIは存在せず、全リポジトリを取得して個別にtemplateRepositoryを確認するしかないという同じ結論が示されていました。
参考: Search repositories that are using a given template #61883
おわりに
gh repo listにテンプレートで絞り込むオプションはありませんでしたが、jqと組み合わせることで実現できました。
定期的に件数を確認したい場合は、cronなどでこのスクリプトを回す運用も検討できそうです。



