GitHub の Ruleset で develop / main への直接 push を禁止する(PR 必須にする最小設定)

目次
「うっかり main に直接 push してしまった」を仕組みで防ぐには、GitHub の Repository ruleset で直接 push を禁止し、Pull Request 経由を強制するのが早いです。この記事では develop と main の 2 本を保護し、PR 必須にする最小構成を、個人〜少人数開発の視点でまとめます。
結論から言うと、効くのは「Require a pull request before merging」ひとつです。ほかは付け合わせ。ただし似た名前の罠(Restrict updates)があるので、そこだけ間違えなければ 5 分で終わります。
最小構成(これだけでOK)
Enforcement status : Active
Target branches : main, develop
Rules : ☑ Require a pull request before merging
☑ Block force pushes
☑ Restrict deletions
Bypass list : 空
以下、各項目を順に説明します。
Ruleset とは(従来の Branch protection との違い)
GitHub には従来からある Branch protection rules と、新しい Rulesets の 2 系統があります。やれること(PR 必須・force push 禁止など)はおおむね重なりますが、Ruleset には次の利点があります。
- 複数ブランチをまとめて 1 つのルールで保護できる(
mainとdevelopを同じ ruleset で対象にできる) - Enforcement status で「有効/評価のみ/無効」を切り替えられる(本番に効かせる前に「評価だけ」して影響を確認できる)
- Bypass list で例外を明示的に管理できる(誰が回避できるかが一覧で分かる)
- 組織レベルでも同じ仕組みで展開できる
新規で作るなら Ruleset を選んでおけばよい、という理解で十分です。作成は Settings → Rules → Rulesets → New branch ruleset から。
1. Enforcement status を Active に
まず一番忘れやすいところ。Active にしないと何も効きません。
Active… ルールを実際に強制するEvaluate… 違反をログに記録するだけでブロックはしない(お試し用)Disabled… 無効
「設定したのに直接 push できてしまう」の大半は、ここが Active になっていないケースです。
2. Target branches に main と develop を追加
保護したいブランチを指定します。ここで注意したいのが Default は「デフォルトブランチ 1 本」しか指さないという点です。デフォルトが main の場合、Default を選んでも develop は保護されません。
なので、次のように両方を明示的に追加します。
Add target→Include by name→mainAdd target→Include by name→develop
release/* のようにワイルドカードでまとめて対象にすることもできます。今回は 2 本なので名前指定で十分です。
3. 本命:Require a pull request before merging
直接 push を弾くのはこのルールです。 チェックを入れると、対象ブランチへは「別ブランチで作業 → PR を出して merge」という経路以外で更新できなくなります。git push origin main は拒否されます。
このルールを開くと Required approvals(必要な承認数) を設定できます。ここが個人開発でよく迷うところなので、使い分けを整理します。
Required approvals は 0 でもいい
| Required approvals | 直接 push | PR のマージ |
|---|---|---|
| 0 | ❌ 禁止 | 承認なしで自分でマージできる |
| 1 以上 | ❌ 禁止 | 他者の承認が必要(レビュー必須) |
ポイントは、0 でも直接 push は禁止されたままということです。「PR は必ず経由させたい。でもレビュー承認は求めたくない(ひとりなので)」という場合は 0 が正解です。
- ひとり開発・とにかく直接 push を止めたいだけ →
0 - 必ず誰かのレビューを通したい →
1以上
0 にしても、PR 画面での差分確認・CI・コンフリクト検知といった恩恵はそのまま受けられます。まず 0 で PR フローに慣れ、チームが増えたら 1 に上げる、という運用がやりやすいです。
このルール配下には他にも便利なオプションがあります(必要に応じて)。
- Dismiss stale pull request approvals when new commits are pushed … 承認後に新しい commit を push したら承認を無効化する(
1以上のときに有効) - Require conversation resolution before merging … レビューコメントが未解決だとマージさせない
4. Block force pushes / Restrict deletions(推奨)
直接 push を止めても、force push やブランチ削除まで塞がないと保護としては片手落ちです。次の 2 つも入れておきましょう。
- Block force pushes …
git push --forceを禁止。履歴の上書き事故を防ぐ - Restrict deletions … 保護ブランチ自体の削除を禁止
この 2 つは副作用がほぼないので、基本オンで問題ありません。
⚠️ 落とし穴:Restrict updates を選んではいけない
名前が紛らわしいのですが、Restrict updates は今回の目的には使いません。
Restrict updates… 「bypass 権限を持つユーザー以外のあらゆる更新を禁止」
これを入れると、直接 push だけでなく PR のマージまでブロックされてしまいます(マージもブランチの「更新」だから)。結果、bypass に入れた人しか何もできなくなり、PR フローが回りません。
「直接 push は止めたいが PR は通したい」なら、使うのは Require a pull request before merging です。Restrict updates は「このブランチは bypass 権限者しか触らせない(例: リリース凍結)」のような、もっと強い制限をかけたいとき用と覚えておきましょう。
同様に Restrict creations(作成禁止)も通常のブランチ保護では不要です。
5. Bypass list は空のまま
Bypass list に入れた対象は、この ruleset を回避して直接 push できます。
- 空にすると、リポジトリ管理者を含めて全員がルールの対象になります(=誰も直接 push できない)
- 「緊急時に自分だけは直接 push したい」なら、自分(や特定チーム/App)を追加する
厳格に「直接 push 全面禁止」にしたいなら空のままが正解です。ここに安易に自分を足すと、結局うっかり push を止められなくなるので、必要になるまで空を推奨します。
なお、CI で自動コミット・自動タグ付けをする GitHub Actions がある場合は、その App/bot を bypass に入れる必要が出てきます。Actions が保護ブランチへ push する構成のときだけ検討してください。
6. CI を必須にしたいなら:Require status checks to pass
「PR は必須。かつ CI(テストや Lint)が通らないとマージさせない」にしたい場合は、Require status checks to pass を併用します。
- チェックしたいワークフロー(status check)の名前を追加する
- Require branches to be up to date before merging … マージ前に最新のベースブランチを取り込ませる(任意)
これで「PR 必須 + CI 通過必須 + 承認は任意(Required approvals: 0)」という、個人開発にちょうどいいラインが作れます。status check は対象ワークフローが一度でも実行されて名前が GitHub に認識されている必要があるので、先に一度 PR を回して CI を走らせてから設定すると迷いません。
まとめ
- 直接 push を止める本命は
Require a pull request before merging Required approvalsは0でも直接 push は禁止できる。ひとり開発なら0で十分Restrict updatesは使わない(PR マージまで止まる)Block force pushes/Restrict deletionsはセットで入れておく- Bypass list は空にすれば管理者含め全員が対象
- CI 必須にしたければ
Require status checks to passを併用 - 忘れがちな
Enforcement status: Activeと、Defaultは 1 本しか指さないの 2 点に注意
まず Required approvals: 0 の PR 必須から始めて、チームや運用が固まってきたら承認数や status check を足していく、という段階導入がおすすめです。
参考ソース
関連記事

デプロイ先の環境をブランチで出し分けるとき、secret を FOO_STG / FOO_PROD のように別名で用意して if 分岐する必要はありません。job の environment をブランチから動的に決めれば、Environment secret として「同じ名前」の secret を各環境に置くだけで自動的に出し分けられます。三項演算子っぽい書き方の仕組みと注意点、承認レビューの掛け方まで解説します。

Terraform の S3 backend が要求する state バケットを、GitHub Actions の OIDC + IAM ロールで手動ワークフローから作成する手順。backend の鶏卵問題、最小権限ロール、冪等な bootstrap、そして role-to-assume が空になるハマりどころまで解説します。

pnpm + Next.js プロジェクトに Renovate を導入し、automerge・依存のグルーピング・lockFileMaintenance を設定する手順を、Mend の Silent mode のハマりどころつきで紹介します。