Git のブランチ戦略まとめ

この記事は [KDDIアジャイル開発センター (KAG) Advent Calendar 2024](https://qiita.com/advent-calendar/2024/kag) の14日目です。

出し尽くされた話題ではありますが、改めて Git のブランチ戦略についてまとめます。

# Git Flow

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408546/8d0676c9-2988-b3d1-7f36-19534b30242e.png)

1. `main` ブランチを取り込んだ `develop` ブランチから `feature` ブランチを作成する
1. `feature` ブランチで開発を進め、開発が完了したら `develop` ブランチにマージする
1. リリースする時点で `release` ブランチに `develop` ブランチをマージする
1. リリース作業は `release` ブランチで行う
    1. リリース作業中にバグ修正が必要であれば `release` ブランチにコミットする
1. リリース作業が完了したら `release` ブランチを `main` ブランチと `develop` ブランチにマージする

### 緊急対応(hotfix)

本番環境でのバグの修正など、緊急対応は `hotfix` ブランチを作成します。

1. `main` ブランチから `hotfix` ブランチを作成し、修正を行う
1. 対応が完了したら `hotfix` ブランチを `main` ブランチと `develop` ブランチにマージする

## 特徴

伝統的なブランチ戦略で、厳密なリリース管理が特徴です。
比較的大規模であったりリリーススパンが長いプロジェクト向きです。

図からもわかるようにブランチの管理が複雑なことがデメリットで、最近は CI/CD の技術が発展してきたことで短いスパンの開発が増えてきていて、あまり利用されない傾向があります。

# GitHub Flow

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408546/a5d1aa6b-d7c9-7fb8-c5b4-dd2e5a57cbed.png)

1. `main` ブランチから `feature` ブランチを作成する
1. `feature` ブランチで開発を進め、開発が完了したら Pull request や CI チェックなどのコードレビューを行う
1. コードレビューが通ったら `main` ブランチにマージされ、CD によって直ちにリリースされる

## 特徴

近年最もよく見られるブランチ戦略かと思います。
名前にもある通り GitHub などのソースコード管理ツールと組み合わせて使うことが前提になっています。
つまり、**Pull request などのコードレビュー体制や CI/CD などコード品質の自動チェック機構、自動デプロイ環境などが整っている**必要があります。

**短いリリーススパンで開発完了したものを即座にリリースしたいプロジェクト**向きです。

デメリットとしては、ブランチ戦略として検証環境へのリリースが組み込まれていないため、**検証環境の管理は別途考える必要がある**点や、即座にリリースされてしまうため、**リリースするタイミングを制御したいプロジェクトには不向き**な点があります。


# GitLab Flow

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408546/5bba1a55-0f4e-20e5-8ebb-91bfb0f2fd46.png)

1. `main` ブランチから `feature` ブランチを作成する
1. `feature` ブランチで開発を進め、開発が完了したら Pull request や CI チェックなどのコードレビューを行う
1. コードレビューが通ったら `main` ブランチにマージする
1. `main` ブランチから `pre-production` ブランチにマージし、CD によって検証環境にリリースする
1. 検証環境での確認が終わったら、 `pre-production` ブランチから `production` ブランチにマージし、CD によって本番環境にリリースする

## 特徴

名前にもある通り GitLab が提唱するブランチ戦略です。
GitHub Flow の弱点を補うために考え出されました。
そのため基本は GitHub Flow に似ています。

違うのは検証環境と本番環境それぞれにブランチが存在する点で、**必ず検証環境を経てから本番環境にリリース**されます。
ブランチ戦略に検証環境→本番環境のリリース順が組み込まれることで厳密に管理することができます。

メリットやデメリットは Git Flow と GitHub Flow のちょうど中間といった感じで、GitHub Flow と比べて厳密なコード管理ができる分、ブランチ管理が複雑になりリリース速度は落ちる点がデメリットになります。


# トランクベース開発

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408546/59030f48-7827-2b41-7082-d6bd23c625c0.png)

1. 運用するブランチはトランク(trunk)と呼ばれる `main` ブランチのみで、コミットごとにリリースします

## 特徴

一番尖ったブランチ戦略ですが、Google が取っているブランチ戦略として有名です。

https://dora.dev/capabilities/trunk-based-development/

`main` ブランチへのコミット単位やマージを**とにかく細かくして頻繁にリリースする**ことが目的で、以下の狙いがあります。

- `main` ブランチマージ時のコンフリクト発生頻度の縮小
    - コミット単位が細かければ変更差分も小さくなり、コンフリクトの発生頻度が下がる
- コードレビュー負担の軽減
    - 変更差分が小さいので即座にレビューが完了する(ペアプロなどでコードレビューなしにもできる)
- 巨大な `feature` マージによるテスト負担の縮小
    - 巨大な変更があると、E2Eテストなど `main` マージ後に行うようなテストが続々と失敗する可能性が高まる

厳密には運用するブランチは1つだけですが、存続期間の短い(せいぜい数時間)2-3個のブランチを運用してもよいそうです(それを表したのが図の下部です)。

しかし高頻度で本番環境にリリースしてしまうわけですから、**高度な自動テスト環境や様々なテクニックを併用する**必要があります。

- CI
    - リリースした後で即座に問題を特定する
- コミット前の自動テスト
    - `git hook` などを用いて、テストに落ちるコードのコミットを防ぐ
- ペアプロなど、即座にコードレビューが可能な体制の構築
- フィーチャーフラグの導入
    - 本番コードには含めるが機能としてはリリースせずに、リリース後の任意のタイミングで機能をオンにできる**フィーチャーフラグ**を使用する

# まとめ

それぞれのブランチが向いているプロジェクトは以下のようになると思います。

- GitFlow
    - 大規模でリリーススパンが長いプロジェクト
- GitHub Flow
    - 高頻度で完成次第即座にリリースを行うプロジェクト
- GitLab Flow
    - GitHub Flow よりは検証環境や本番環境へのリリースタイミングの管理などを厳密に行いたいプロジェクト
- トランクベース開発
    - GitHub Flow 以上に高頻度でリリースを行いフィードバックを受けたいプロジェクト