複数人で開発を始めると、「ブランチをいつ切り、いつ戻すか」というルールが必要になります。
ルールが曖昧なままだと、長く放置されたブランチのマージで衝突が多発したり、どの状態が本番に出ているのか分からなくなったりします。
この記事では、小〜中規模のチームでよく選ばれる GitHub Flow とトランクベース開発について、進め方の違いと選び方、運用の注意点を解説します。
ブランチ戦略で決めること
ブランチ戦略とは、チームでブランチを扱うときの約束事です。
名前の付け方だけでなく、次のような点を決めます。
- どのブランチを「常に動く状態」として扱うかを決める。
- 作業用のブランチを、どのくらいの期間で取り込むかを決める。
- 取り込む前に、誰が何を確認するかを決める。
- どのタイミングで本番に反映するかを決める。
GitHub Flow とトランクベース開発は、どちらも「メインのブランチを1本に絞り、そこへ頻繁に変更を取り込む」という点で共通しています。
違いが出るのは、作業ブランチの長さと、取り込む前の確認の仕方です。
GitHub Flow の進め方
GitHub Flow は、GitHub のドキュメントで紹介されている、プルリクエスト(PR)を中心にした進め方です。
公式ドキュメントでは、次の流れが示されています。
- ブランチを作る(短く、内容が分かる名前にする)。
- 変更をコミットし、プッシュする。
- プルリクエストを作り、レビューを依頼する。
- レビューの指摘に対応する。
- 承認されたら、デフォルトブランチへマージする。
- マージしたブランチを削除する。
コマンドで書くと、1つの変更は次のようになります。
git switch main
git pull
git switch -c fix/contact-form-validation
# 編集してコミット
git add .
git commit -m "fix: 問い合わせフォームの入力チェックを修正"
git push -u origin fix/contact-form-validation
# GitHub上でPRを作り、レビュー後にマージ
git switch main
git pull
git branch -d fix/contact-form-validation
ブランチの削除は、作業の完了を示し、誤って使い回すことを防ぐためです。
削除しても、PR とコミットの履歴は残ります。
当社のこのサイトも、main への直接の push を禁止し、feat/…、fix/…、chore/… のブランチから PR を作る運用にしています。
main へのマージが Cloud Run への本番デプロイにつながるため、「main は常にデプロイできる状態」という前提が、そのまま運用ルールになっています。
トランクベース開発の進め方
トランクベース開発は、全員がトランク(main などの1本のブランチ)へ、小さな変更を頻繁に取り込む進め方です。
作業ブランチを使う場合も、寿命をごく短くし、長く並行して育てることはしません。
Google Cloud の DevOps に関する解説(DORA の研究に基づくもの)でも、継続的デリバリーを支える技術の1つとして紹介されています。
GitHub Flow との違いを、表にまとめます。
| 観点 | GitHub Flow | トランクベース開発 |
|---|---|---|
| 作業ブランチ | 機能や修正ごとに作る | 作らないか、ごく短命にする |
| 取り込む単位 | PR 1件(1つの機能・修正) | 小さな変更を1日に何度も |
| 確認の中心 | PR のレビュー | 自動テストと、小さな差分のレビュー |
| 未完成の機能 | ブランチの中で完成させる | フィーチャーフラグなどで隠して取り込む |
| 向くチーム | 少人数〜中規模、レビューを重視 | 自動テストが充実し、頻繁にリリースする |
トランクベース開発の要点は、「未完成でもトランクに入れてよいが、利用者には見せない」ことです。
そのために、設定で機能の有効・無効を切り替えるフィーチャーフラグをよく使います。
import os
# 環境変数で新しい検索画面の公開を切り替える
NEW_SEARCH_ENABLED = os.getenv("NEW_SEARCH_ENABLED", "false") == "true"
def search_page():
if NEW_SEARCH_ENABLED:
return render_new_search()
return render_old_search()
この形なら、新しい検索画面の実装を少しずつトランクへ取り込みながら、本番では古い画面を出し続けられます。
完成したらフラグを有効にし、問題がなければ古いコードとフラグを削除します。
どちらを選ぶか
迷ったときは、次の観点で判断します。
- 自動テストが少ないなら、PR のレビューを品質の歯止めにできる GitHub Flow から始める。
- 1日に何度もリリースしたい、またはブランチの衝突に悩んでいるなら、トランクベース開発に寄せる。
- 社外の協力者が参加するなら、PR で変更を受け取る GitHub Flow が扱いやすい。
- フィーチャーフラグを管理する仕組みがないなら、まず小さな PR を頻繁に出す GitHub Flow で慣れる。
実際には、両者は対立するものではありません。
GitHub Flow で「PR を小さくし、その日のうちにマージする」運用を続けると、トランクベース開発にかなり近づきます。
注意点・落とし穴
ブランチが長生きする
GitHub Flow で最も多い失敗は、1つのブランチに機能を詰め込み、数週間マージしないことです。
main との差が広がるほど衝突が増え、レビューも難しくなります。
「1つの PR は1つの目的」「差分は数百行以内」のように、チームで目安を決めておきます。
main が壊れる
どちらの方式も、main が常に動く状態であることが前提です。
GitHub のブランチ保護ルールを使うと、マージ前のレビュー承認や、ステータスチェック(CI のテスト)の成功を必須にできます。
人の注意だけに頼らず、仕組みで止めるようにします。
フィーチャーフラグが残り続ける
トランクベース開発では、使い終わったフラグを消し忘れると、条件分岐が増えてコードが読みにくくなります。
フラグを作るときに、削除する時期や担当者を Issue などに記録しておきます。
マージの方法がそろっていない
マージコミット、スカッシュマージ、リベースマージが混在すると、履歴が追いにくくなります。
リポジトリの設定で、許可するマージの方法を絞っておくと、運用がそろいます。
まとめ
GitHub Flow は「PR とレビューで品質を守る」方式で、少人数のチームや自動テストがまだ少ない段階に向いています。
トランクベース開発は「小さな変更を頻繁にトランクへ入れ、自動テストとフラグで安全を保つ」方式で、リリース頻度を上げたいチームに向いています。
どちらを選ぶ場合も、ブランチを短命に保つことと、main をブランチ保護で守ることが、最初に整えるべき土台です。