「新人がmainを直接更新してしまった!」なぜブランチ保護が必要なのか

広告

Gitを使ったチーム開発では、こんな話を聞くことがあります。

「新人がmainブランチを直接更新してしまった」

これは決して珍しい種類の事故ではありません。

Gitに慣れていない人だけでなく、現在どのブランチにいるのか確認し忘れたり、操作を勘違いしたりすることで、経験者でも起こす可能性があります。

今回は、

  • なぜmainを直接更新すると問題なのか
  • どんな操作で事故が起こるのか
  • Pull Requestは何のためにあるのか
  • mainを守る仕組みとは何か

を初心者向けに説明します。mainブランチを守る考え方の全体像は、GitHubでmainブランチを守ろうでも紹介しているので、あわせて参考にしてください。

mainブランチとは

Gitでは、複数のブランチを作って並行して開発できます。

その中でもmainは、一般的に現在の正式な状態を管理するために使われる重要なブランチです。(ブランチ名をmasterにするかmainにするかで迷った場合は、masterとmain、どちらを使うべきかも参考にしてください。)

例えば次のような構成です。

main
 ├─ feature-login
 ├─ feature-search
 └─ feature-setting

各担当者は自分の作業ブランチで開発し、完成した変更をmainへ取り込みます。基本的な流れは、

main
  ↓
作業ブランチを作成
  ↓
コードを変更
  ↓
Commit
  ↓
Push
  ↓
Pull Request
  ↓
レビュー
  ↓
mainへMerge

となります。

「mainを直接更新する」とは?

例えばGitHub Desktopで現在のブランチがmainになっている状態で、そのままVisual Studioでコードを変更したとします。その後、

Commit
↓
Push origin

すると、変更がそのままmainへ送られる可能性があります。本来、feature-aのような作業ブランチで変更する予定だったものを、mainで変更してしまったわけです。これが、「mainを直接更新してしまった」という状態です。

何が問題なの?

mainを直接更新すると、Pull Requestによる確認工程を通りません。つまり、

コードを書く
↓
自分でCommit
↓
そのままmainへPush

となります。この場合、次のような問題が起きやすくなります。

  • 他のメンバーがコードを確認する機会がないまま、動かないコードやバグがmainに混ざってしまう
  • CI(自動テストやビルド)を通さずにmainが更新され、チーム全体の動作確認が後回しになる
  • 他のメンバーの変更とのコンフリクト(競合)に、誰も気づけないまま進んでしまう

一方、Pull Requestを利用すると、

コードを書く
↓
作業ブランチへPush
↓
Pull Requestを作成
↓
他のメンバーが確認
↓
問題があれば修正
↓
Merge

という流れになります。ここに大きな違いがあります。

よくあるパターン1:ブランチを切り替え忘れる

例えば前日にmainへ切り替えたまま作業を終了し、翌日Visual Studioを開いてそのままプログラムを修正してしまうことがあります。本人はfeature-aで作業しているつもりでも、実際にはmainだった、というケースです。GitHub Desktopでは画面上部のCurrent branchを確認する習慣が重要です。

よくあるパターン2:Pull Requestを使わずにPushしてしまう

初心者の場合、

Commitした
↓
Push originが表示された
↓
押した

という操作になりがちです。GitHub DesktopではPush自体は非常に簡単なので、どのブランチをPushしているのかを理解していないと、意図せずmainへPushしてしまう可能性があります。大切なのは、Pushが危険なのではなく、現在どのブランチにいるのか理解してPushすることです。

よくあるパターン3:Force Pushで履歴を書き換えてしまう

さらに危険なのが、Force Push(強制的にリモートの履歴を上書きするPush)です。通常のPushでは、Gitはリモート側の履歴と矛盾する変更を簡単には受け付けません。しかしForce Pushを使うと、リモートブランチの履歴そのものを書き換えることができます。

GitHub公式ドキュメントでも、Force Pushによって、他のメンバーが作業の基点としていたコミットがブランチ履歴から削除される可能性があると説明されています。(GitHub Docs)そのため、特にmainに対するForce Pushは慎重に扱う必要があります。

「新人が悪い」で終わらせてはいけない

ここで重要なのは、新人だから失敗したで終わらせないことです。人は操作を間違えます。経験者でも、

  • ブランチを見間違える
  • Push先を間違える
  • Merge対象を間違える
  • 操作手順を勘違いする

といったことは起こります。そのためチーム開発では、気をつけるだけではなく、間違えても事故にならない仕組みを作ります。

mainを守る仕組み:Protected Branch

GitHubには、Protected Branchつまり「保護されたブランチ」という仕組みがあります。mainを保護すると、例えば次のようなルールを設定できます。

  • mainへの直接Pushを制限する
  • Pull Requestを必須にする
  • レビュー承認を必須にする
  • Force Pushを禁止する
  • ブランチ削除を禁止する

GitHub公式ドキュメントでも、Protected branchesではPull Requestのレビュー要求、Force Pushの制限、ブランチ削除の制限などを設定できると説明されています。(GitHub Docs)実際の設定手順はGitHub Rulesetsでmainブランチを保護するで画面付きで解説しているので、あわせて確認してください。

補足:Copilotによる自動レビューと組み合わせる

Protected Branchで「Pull Requestを必須にする」ところまで仕組み化できたら、レビューそのものをGitHub Copilotに自動で行わせることもできます。設定手順は次の通りです。

  1. リポジトリの Settings を開く
  2. サイドバーの Code, planning, and automation → Copilot → コードレビュー を開く
  3. Branch rules(ブランチルール)で「Automatically request Copilotコードレビュー」を選択する

これにより、新しいプルリクエストに対してCopilotのレビューが自動的にリクエストされるようになります。ルールセット設定で「新しいプッシュの確認」を選択すれば、Pushのたびに再レビューを自動で要求することもできます。

ただし注意点として、Copilotはあくまでレビューコメントを付ける役割です。Protected Branchの「レビュー承認を必須にする」設定と組み合わせても、Copilotの指摘そのものが自動でマージをブロックするわけではありません。最終的な承認は引き続き人間が行う仕組みとセットで使うのが安全です。

レビューの徹底度(作業量レベル)も選べるため、複雑なロジックやセキュリティに関わるコードには、より詳細な分析を行うレベルを選ぶこともできます。Copilotレビューの使い方や役割分担については、GitHub CopilotにPull Requestを自動レビューしてもらうで詳しく解説しています。

mainを守ると開発の流れが変わる

mainを保護してPull Requestを必須にすると、開発者は基本的に次の流れで作業します。

main
 ↓
作業ブランチ作成
 ↓
プログラム変更
 ↓
Commit
 ↓
Push
 ↓
Pull Request
 ↓
レビュー
 ↓
Merge
 ↓
main

これなら、間違ってmainを直接更新しようとしても、GitHub側のルールで止めることができます。

Pull Requestは「許可をもらうだけ」の機能ではない

初心者のうちは、Pull Request=mainへ入れてもらうための申請と考えがちです。もちろんそれも役割の一つですが、より重要なのは、変更内容をチームで確認する場所であることです。Pull Requestを見ることで、

  • どのファイルを変更したか
  • 何行追加したか
  • 何行削除したか
  • どんなコードを書いたか
  • なぜ変更したのか

を確認できます。つまりPull Requestは、コードレビューの入口でもあります。

Gitのルールは面倒だから存在するのではない

初めてチーム開発をすると、わざわざブランチを作る、Pushする、Pull Requestを作る、レビューする、Mergeするという手順を見て、直接mainを変更した方が早いのでは?と思うかもしれません。確かに1人で作業しているだけなら、その方が早い場合もあります。しかしチーム開発では、誰が何をなぜ変更したのかを共有する必要があります。そのための仕組みが、Branch・Commit・Pull Request・Review・Mergeです。

「気をつける」より「仕組みで防ぐ」

例えば、mainは絶対に直接変更しないでくださいと口頭で説明するだけでも、ある程度の効果はあります。しかし16人で開発していたら、16人全員が毎回必ず正しい操作をするとは限りません。そこで、mainへ直接Pushできないように設定しておけばよいわけです。

これはGitだけの考え方ではありません。システム開発では、「注意してください」より「そもそも間違った操作ができない」設計の方が安全です。

初心者こそPull Requestを経験しておこう

学習中は、自分しか使わないアプリだからmainだけでいいと思うかもしれません。しかし、チーム開発を経験するのであれば、作業ブランチを作る→Commit→Push→Pull Request→レビュー→Mergeまで一通り経験しておくことには意味があります。実際に4人チームでPR・レビューを回す流れは4人で作るPR・レビュー付きチーム開発で体験できます。重要なのはGitのボタン操作を覚えることだけではありません。なぜこの手順が必要なのかを理解することです。

もし事故が起きてしまったら

仕組みで防いでいても、万が一mainを直接更新してしまった場合は、慌てずに対処することが大切です。

  • 直前のCommitを打ち消したいだけなら、git revertで新しいCommitとして変更を打ち消す(履歴を書き換えないため安全)
  • Push前であれば、そのままPushせずチームに相談する
  • すでにPush済みで、リポジトリの管理者権限がない場合は、自己判断でForce Pushして直そうとせず、必ずチームのリーダーやGitHub管理者に連絡する

特に「間違えたことを隠さずすぐ共有する」ことが、被害を広げないための一番のポイントです。

まとめ

「新人がmainを直接更新してしまった」というのは、Gitを使う現場で起こり得る典型的な事故の一つです。しかし、本当に大切なのは、誰が間違えたのかではありません。考えるべきなのは、どうすれば同じ事故が起きないかです。

そのためにGitHubでは、作業ブランチ・Pull Request・コードレビュー・Protected Branch、そしてCopilotによる自動レビューといった仕組みを利用します。チーム開発の基本形は、

mainを直接編集しない
↓
作業ブランチで変更する
↓
Pull Requestで確認する
↓
レビュー後にmainへMergeする

です。

Gitのルールは、作業を面倒にするためにあるのではありません。チーム全体のコードを安全に守るためにあります。そして、「間違えないように注意する」だけでなく、「間違えても壊せない仕組みにする」ことが、チーム開発では重要です。

参考

  • GitHub Docs:About protected branches
  • GitHub Docs:Configuring automatic code review by Copilot
訪問数 6 回, 今日の訪問数 6回

広告

Git,チーム開発

Posted by hidepon