結局 Git のブランチ戦略ってどうすればいいの？

:::note info


2024/11/7 オフライン勉強会開催のお知らせ
弊社[ミライトデザイン](https://miraito-inc.co.jp)主催で本記事のハンズオン勉強会を開催します。

オンライン配信もありますので、お気軽にご参加ください。

[【サクッと!!】Laravel ローカル開発環境構築ハンズオン【初心者歓迎】](https://phper-oop.connpass.com/event/333013)
:::


## 背景

9/5に開催された弊社ミライトデザインが運営しているペチオブ勉強会に参加しました。

https://phper-oop.connpass.com/event/326850

みんなで話し合ったGit運用の中のブランチ戦略パターン(**Git Flow**, **GitHub Flow**, **GitLab Flow**, **Trunk Based Development**)について勉強して、個人的に情報を整理したいなと思ったので記事にしました。
イベントの動画や議事録もconnpassのリンクから確認できます。

## PR

:::info
弊社[ミライトデザイン](https://miraito-inc.co.jp)では、他にも様々なお役立ち記事や動画、勉強会を公開しています。よかったら[ミライトデザインOrganizationページ|Qiita](https://qiita.com/organizations/miraito-inc)、[MIRAITO CHANNEL|YouTube](https://www.youtube.com/c/MiraitoDesignInc)、[ペチオブ|connpass](https://phper-oop.connpass.com)も覗いてみてください！

また、ミライトデザインでは一緒に働く仲間も募集しています！興味をお持ちいただける方は、[こちら](https://miraito-inc.co.jp/contact)まで！
:::

## Git、GitHub、GitHub Actionsシリーズ記事のまとめ

https://qiita.com/ucan-lab/items/33c63a402f533aa92f3e

## 目的

ブランチをどう運用するのかはチームごとに異なります。
数人のチームなのか、数十人のチームなのか規模によっても最適な運用ルールは変わります。
何が私たちにとって最適なのか、みんなで考えたいと思います。
他のチームではどういった運用をされてるのか知りたいのでぜひコメントしてください。

## ブランチ戦略とは

Gitのブランチを**どういうタイミングでいつ何のためにマージするのかを考える**のがブランチ戦略です。

## コラム: `main` と `master`

2021年6月7日以降に作成されるGitリポジトリは、デフォルトブランチ名が `master` から `main` に変わりました。

Gitのブランチ名のデフォルトが `master` でした。この用語は一部の人々から不快になるため名称が `main` に変更となりました。

https://sfconservancy.org/news/2020/jun/23/gitbranchname/

## GitHub Flow

![GitHub Flowの図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/d7dbadf7-088d-1eff-7fa3-58f6de0aea32.png)

https://docs.github.com/ja/get-started/using-github/github-flow

まずはシンプルなブランチ戦略なGitHub Flowから紹介します。

- `main` ブランチ
- `feature` ブランチ

`main` ブランチから `feature` ブランチを作成し、開発が完了したら `main` ブランチへPull Requestを作ってマージする。

`main` ブランチは常にデプロイ可能な状態に保ちます。
`main` ブランチへ直接コミットするのではなく、新しい機能や修正を `feature` ブランチで行ったらPull Requestを作成して `main` ブランチへマージします。

作業が完了したらプルリクエストを作成し、コードレビューとフィードバックを行い、承認されたら `main` ブランチにマージします。

### メリット

GitHub Flowのメリットはとにかくシンプルさ。
`feature` ブランチの寿命が短く、頻繁に `main` ブランチにマージされるため大きなコンフリクトの発生する可能性が減ります。

シンプルな構成のためCI/CD(継続的インテグレーション/継続的デプロイメント)ツールと連携しやすく自動テストや自動デプロイが実行されるため、開発プロセス全体の効率が向上します。

主に小規模なチームやスタートアップな開発に適しています。

### デメリット

長期間の開発が必要な大規模なプロジェクトや複数のリリースを並行して進める必要がある場合、GitHub Flowは適していません。

`main` ブランチが常に最新の安定版であることを前提としているため、大規模な新機能やリファクタリングを進行中の状態で保持することが難しいです。
また開発環境、ステージング環境、本番環境など複数の環境を使い分ける場合はブランチ戦略がシンプルすぎるため環境ごとのデプロイ管理が煩雑になる可能性があります。

未完成の機能をデプロイしないようにするため、機能フラグや環境ごとに分岐する等を行う場合はこれを管理する手間になる可能性があります。

開発規模が大きくなる場合は何らかの対応を行う必要がある([feature toggle](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%BC%E3%83%81%E3%83%A3%E3%83%BC%E3%83%88%E3%82%B0%E3%83%AB)など)ブランチ戦略です。
もしくは次に紹介するGit Flowの導入を検討してみましょう。

### 個人的な感想

GitHub Flowは個人的に一番好きなフローではあるが、実務で使用するには少しシンプル過ぎる。小規模開発にはとてもオススメです。
プロジェクト開始時はこの運用で進めて、規模が大きくなってきたら `develop` ブランチを導入する、もしくは環境が増えたらGitLab Flowへ移行すると良いと思います。

## コラム: コミットのメッセージと粒度

- 1 Commit は1つの意味あるまとまりであるべき
	- 差分が大きくなっても意味があるまとまりなら問題なし
	- 意味の異なる変更が含まれる場合はタスクを分けるべき
- 1 Issue、1 Pull Request、1 Commit が理想
- 1 Issue 1 Commit となるようなタスクの切り方が大事
- タスク管理ツールによっては特定のブランチ名やコミットメッセージで紐付けができるので活用したい

### INVESTの原則

Issue を適切な大きさで切り出すためにはスクラムのガイドラインであるINVESTの原則を参考にすると良いです。

|頭|単語|意味|
|:---:|:---:|:----- |
|I|Independent|独立している|
|N|Negotiable|交渉可能|
|V|Valuable|価値がある|
|E|Estimatable|見積もり可能|
|S|Small|小さい|
|T|Testable|テスト可能|

https://kray.jp/blog/attractive-product-backlog/

1つのIssueが大きくなると1 Pull Requestで大量の差分が発生します。
そうなるとレビュワーに負担がかかり、コンフリクトの可能性も高まり、コードレビューを効率よく進めることができません。

このINVEST原則を守ることでチームはより効果的に作業を進め、柔軟に対応して開発を進めることができます。

## Git Flow

![Git Flowの図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/d3991ece-6f24-f08c-da3c-9b8dd805d140.png)

https://nvie.com/posts/a-successful-git-branching-model

Git Flowは5種類(`main`, `hotfix`, `release`, `develop`, `feature`)のブランチを運用するブランチ戦略です。

2010年に提唱された有名なブランチ戦略です。
オンラインサービスのように継続的デリバリーするコードを想定して作られた戦略ではないです。

- `main` ブランチ
	- 常にリリースできる状態を保つ
	- `hotfix`, `develop` へ切り出す
	- このブランチへの直pushはNG
- `hotfix` ブランチ
	- バグ修正など緊急時に対応するためのブランチ
	- `main` ブランチから分岐する
	- `main` と `develop` ブランチへPull Requestを作成してマージする
	- マージ後はブランチを削除する
	- このブランチへの直pushはOK
- `release` ブランチ
	- リリースに向けた最終的な調整を行うブランチ
		- バグ修正、ドキュメントの更新、バージョン番号のインクリメント等
		- 主に安定化を目的としているため、新機能の追加は行われません
		- 通常はバージョン番号をブランチ名に付けます(例: `release/1.0.0`)
	- `develop` ブランチから分岐する
	- `main` と `develop` ブランチへPull Requestを作成してマージする
		- リリースブランチが作成された段階でリリースの準備がすでに整っており、特に追加の修正や調整が不要な場合は `develop` ブランチと差分がないためマージしない場合もあります
	- マージ後はブランチを削除する
	- このブランチへの直pushはOK
- `develop` ブランチ
	- 開発用のブランチ
	- `main` ブランチから分岐する
	- `feature`, `release` ブランチへ切り出す
	- マージ後はブランチを削除しない
	- このブランチへの直pushはNG
- `feature` ブランチ
    - `feature` は英語で「機能」や「特徴」を意味し、新しい機能やバグ改修を実装するために用いられる
	- `develop` ブランチから分岐する
	- `develop` ブランチへPull Requestを作成してマージする
	- マージ後はブランチを削除する
	- このブランチへの直pushはOK
- `support` ブランチ
	- 旧版をサポートするためのブランチ
	- オプションなので使用しない場合が多い

### メリット

- `main` は常にリリース可能な状態を保てるため、品質が保証される
- 原則、`release` ブランチからマージされるため、履歴がシンプルで追跡しやすい
- リリース準備中も `develop` ブランチでの開発を並行して行えるため、意図せず開発中の機能をリリースしてしまうリスクが減る

### デメリット

- 学習コストが高い
	- ブランチ運用のルールが多く、初心者や小規模チームにとっては理解と実践に時間がかかる
- リリースブランチの長期維持の負担
	- 長期間にわたるリリースブランチの維持は、`develop` ブランチとの同期が必要となり、管理が煩雑になる可能性がある
- マージをする人の負担が大きい
	- `feature` ブランチが大きくなりがちなため、大きい差分を確認する負担が大きい
- 複数リリースの並行管理が難しい
	- 複数のリリースが並行して進行する場合、Git Flowではリリースブランチ間の管理が難しい
- 複数のブランチからのマージが発生する
	- 特にdevelopブランチは`feature`, `release`, `hotfix` からマージされる
	- CI/CDの実行時間が長くなり、GitHub Actionsなど無料利用枠を超えるとジョブの実行時間により課金される可能性が増える
	- 設定が複雑になり、設定ミスの可能性が増える
- `feature` ブランチが長期間生存することになるため、ビッグバンマージが発生しやすく、コンフリクトになる可能性も高い

:::note warn
提唱者の Vincent Driessen さんが 2020年に書かれた反省のメモに書かれています。

Web アプリは通常、ロールバックされることなく継続的に配信され、実際に実行されているソフトウェアの複数のバージョンをサポートする必要がありません。
Git Flow をチームに無理やり押し込もうとするのではなく、はるかに単純なワークフロー (GitHub Flow など) を採用することをお勧めします。

ただし、明示的にバージョン管理されたソフトウェアを構築している場合、またはソフトウェアの複数のバージョンをサポートする必要がある場合は、過去 10 年間の人々にとってそうであったように、Git Flow は今でもチームに適している可能性があります。
:::

### 個人的な感想

プロジェクトでよくこの形を見かけはするが、これ通りに運用されてるのはあまり見ない。
hotfixブランチも結局 `develop` → `release` → `main` とマージしてるのも見るし、`release` ブランチを作らず `develop` → `main` とマージするのも見る。

毎日デプロイするとか、リリースサイクルが早いプロジェクトではさすがにしんどいですね。週1でもデプロイコストがなかなか高い気がします。

Vincent Driessen さんの反省メモにも書かれている通り、WebアプリにおいてGit Flowはオーバースペックになる場合があるため、導入する際はチームに適した形を一度検討すると良いでしょう。

## GitLab Flow

![GitLab Flowの図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/be48ebe1-0638-8040-9fad-4e9685412f4c.png)

https://about.gitlab.com/ja-jp/topics/version-control/what-is-gitlab-flow

GitLab Flowは「GitHub Flow + 各環境用のブランチ」という感じです。

- `main` ブランチ
	- 常にリリースできる状態を保つ
	- このブランチへの直pushはNG
- 各環境 ブランチ
	- `staging`, `production` など各環境に対応したブランチを作成する
	- マージ後はブランチを削除しない
- feature ブランチ
	- 新しい機能や特定の作業を進めるために使用するブランチ
	- `main` ブランチから分岐する
	- `main` ブランチへPull Requestを作成してマージする
	- マージ後はブランチを削除する

### メリット

- 環境ごとのブランチ運用が可能
  - 明確に分けることでデプロイやテストがしやすくなる

### デメリット

- 環境ごとにブランチがあるため、運用がしっかりしていないと混乱の恐れがある

## Trunk Based Development

![Trunk Based Developmentの図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/f7a3f4b7-7165-99cc-dee6-eaf3c5c378e3.png)

https://trunkbaseddevelopment.com
https://www.atlassian.com/ja/continuous-delivery/continuous-integration/trunk-based-development

- `main` ブランチ
	- まさにメインで開発を進めるブランチ。トランクベース開発では直pushもOKとする
	- コミットがpushされたら、自動ビルド＆テスト
- `feature` ブランチ
	- 新しい機能や特定の作業を進めるために使用するブランチ
	- このブランチへの直pushはOK
	- コミットがpushされたら、自動ビルド＆テスト
	- `main` ブランチから分岐する
	- `main` ブランチへPull Requestを作成してマージする
		- ペアプロ、モブプロを行ってコードレビュー済みであればPR作らずマージしても良い
	- できれば1日以内にマージする。最長でも3日以内にマージする制約がある
	- マージ後はブランチを削除する
- `release` ブランチ
	- リリースのためのブランチ
		- Git Flowの `hotfix` ブランチの代わり
	- `main` ブランチから分岐する
	- `release` ブランチにコミット、マージは行わない
		- バグ修正は `main` ブランチにコミットを積む
			- `release` ブランチで行ってしまうと `main` ブランチへのマージバックが忘れやすいため
		- 必要なコミットは `cherry-pick` で `release` ブランチに持ってくる

トランクベース開発はトランク(`main` ブランチ)へPull Requestを使わずにどんどんコミットしていこうという大胆な戦略です。

チーム人数が増えると現実的じゃないのでその時は `feature` ブランチを作ってPull Requestを使ってマージします。
(この場合はGitHub Flowに近い運用です)

ただ、この場合においてもPull Requestが作成されてからマージされるまで基本的に1日で行います。長くとも3日以内に行う制約があります。

長期間生存するブランチは `main` ブランチのみです。

とにかく `feature` ブランチの生存期間をできるだけ短くして、ソースコードの大規模なマージを避けて、コンフリクトを減らし、開発スピードを上げることが目的になっている戦略です。

想像してみましょう。半年、数年かけて育てた `feature` ブランチをリリースが近づき、`develop` にマージするタイミングで発生する大量のコンフリクト...
もし手作業で数百ファイルに及ぶコンフリクトを解消するとなると解消の規模、工数の予測ができなくなる恐怖😱
長期の開発中に他のブランチでリファクタリングなどが行われているとこのようなことが発生します。

トランクベース開発で `main` に積極的にマージを行うことで、多少のミスは発生しやすくなります。
マージの規模は最小限で済むため、大きい問題が発生する可能性は低くなります。

#### 自動テスト

トランクベース開発は自動テストが前提のブランチ戦略です。
開発者はプロダクションコードとテストコードを合わせてコミットします。
CIでエラーが発生したら開発を即止めて修正を行います。

#### コードレビュー

トランクベース開発はコードレビューのプロセスが重要です。

- レビュープロセスを重くしない
	- 複数の機能をまとめない
	- 機能追加とリファクタを同時に行わない
	- etc
- マージ前にレビューする場合は、依頼を受けたら即対応する
	- 1日でマージするため依頼があれば即対応する
	- 自動テストが運用できていればマージした後にレビューしても良い
		- CIでエラーが発生したら即対応するため安心してマージして良い
		- あとからリファクタリングで良い
- ペアプロ、モブプロ
	- ペアプロで開発しているのであればその場でレビュー済みであるため、`main` ブランチへ直接pushでも良い
	- どのみちCIでエラーが出たら即対応する
- AIコードレビューを活用する
	- レビューの負担を軽減できる
	- AIが必ず正しい訳ではないので、最終的には開発者が取捨選択する
	- AIレビューサービス
		- [Amazon CodeGuru](https://aws.amazon.com/jp/codeguru)
		- [PR Agent](https://github.com/Codium-ai/pr-agent)
		- [CodeRabbit](https://coderabbit.ai/ja)

#### デプロイとリリースの分離

ビジネスの判断により、この日までは機能を見せたくないといった場合はもちろん発生します。
トランクベース開発は　`main`　ブランチにマージするため、デプロイとともに開発中の機能がリリースされてしまう問題があります。

コード自体は本番環境へデプロイするが、リリースは行わないようにします。

- API先行開発
	- APIの部分だけ先行で開発を進めてリリース日までは画面の実装は進めない
- DIによる差し替え
	- DI(依存性の注入)を利用してリリース日まではモックが動くようにします
- フィーチャーフラグ(機能フラグ)
	- フィーチャーフラグを導入して機能のオン・オフが行えるようにする
	- フィーチャーフラグサービス
		- [AWS AppConfig](https://docs.aws.amazon.com/ja_jp/appconfig/latest/userguide/what-is-appconfig.html)
		- [Laravel Pennant](https://readouble.com/laravel/11.x/ja/pennant.html)
			- Laravelエンジニアだったのでご紹介してます

つまり、開発環境、検証環境、本番環境へは同じコードがデプロイされていて、フィーチャーフラグを用いて必要な環境で機能を個別に有効化していくという考えになります。 ※すべての環境へ同時にデプロイするという訳ではない。

#### リリース

トランクベース開発ではリリースするタイミングで、`main` ブランチから `release` ブランチを切り出します。
Git Flowにおける `hotfix` ブランチの代わりとなります。

`main` ブランチはリリース準備中もどんどんマージが進むため、リリースするタイミングでは開発中のコミットを含めたくないです。

`release` ブランチではコミット、及びマージは行いません。
バグ修正のコミットは `main` ブランチへpushします。
必要なコミットはマージではなく、`cherry-pick` で `release` ブランチへ取り込みます。

`release` ブランチでバグ修正コミットを行うと `main` ブランチへのマージバックが忘れやすくなるためです。
`release` ブランチを切り出す時は最新の `main` ブランチではなく、安定してるコミットから切り出しても良いです。

`release` ブランチ上で手動テスト、検証を行い、問題なければデプロイします。

#### テスト

- ユニットテストをデータベースなどにボトルネックになる外部コンポーネントには依存させない
- テストをステートレスにしてコンテナ環境で並列実行させる
- テストグループを作成してローカルで関連テストのみ実行して開発者の負担を減らす

## コラム: 継続的インテグレーションとは？

継続的インテグレーションとは？
https://aws.amazon.com/jp/devops/continuous-integration/

> **継続的インテグレーション**は、開発者が自分のコード変更を定期的にセントラルリポジトリにマージし、その後に自動化されたビルドとテストを実行する [DevOps](https://aws.amazon.com/jp/devops/) ソフトウェア開発の手法です。

`main` ブランチへマージされた直後に行われる自動ビルド&テストのことを継続的インテグレーションと呼び、`feature` ブランチを用いて、自動ビルド&テストすることは継続的インテグレーションとは呼ばれません。

- CB: 継続的ビルド(Continuous Build)
	- コードをpushしたら自動的にビルド&テスト
- CI: 継続的インテグレーション(Continuous Integration)
	- コードを `main` ブランチにマージしたら自動的にビルド&テスト
- CD: 継続的デリバリー(Continuous Deliver)
	- 継続的インテグレーションのあと自動的にテスト環境または運用環境 (あるいはその両方) にデプロイ

## コラム: なぜブランチ戦略が必要なのか？

ブランチ戦略を導入することでメリットがあります。

- 作業の並行化
	- 本番用のコードに影響を与えず、並行して開発を進められる
- ブランチ命名ルールの統一
	- ブランチ名から目的の意図が汲み取れるためブランチの内容理解が短縮する
- オンボーディングの効率化
	- ルールに沿ったブランチ戦略が運用されていることで新規参入メンバーが迅速に作業に取り掛かれる
- リリースタイミングの調整
	- リリースのためのブランチと開発のためのブランチなど目的ごとに用意することで開発が効率良く進められる
- コードレビュー
	- プルリクエストを利用してブランチをマージするのでチーム内でコードレビューを行う機会を提供できます
	- コードの品質が向上し、チーム内の知識共有が促進される
- CI/CD
	- ルールに沿って運用されることで自動化スクリプトやCI/CDツールの導入が容易になる

## コラム: ブランチの名称について

- `main` ブランチ
	- 歴史的な経緯から `master`, `trunk` と呼ばれることがあります
	- [Trunk(トランク)](https://ja.wikipedia.org/wiki/%E3%83%88%E3%83%A9%E3%83%B3%E3%82%AF_(%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2)#:~:text=%E3%83%88%E3%83%A9%E3%83%B3%E3%82%AF%20(%E8%8B%B1%3A%20trunk)%E3%81%A8,%E3%81%AF%E5%90%8D%E5%89%8D%E3%81%8C%E3%81%A4%E3%81%84%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E3%80%82)はSubversion時代の `main` ブランチの呼び名です
- `feature` ブランチ
	- `topic` ブランチとも呼ばれることがあります

## コラム: デプロイタイミングについて

そのプロジェクトによるし、ブランチ戦略によるし、色々あるとは思いますが、個人的なおすすめとしては本番環境はタグを付けたタイミングで自動デプロイをお勧めします。

プロジェクトによってどんな環境が用意されるか様々...呼び方も様々...予算も様々...ありますが、Git Flowの場合の例をご紹介します。

ローカル環境、開発環境、評価環境、ステージング環境、本番環境の5つあるケースです。

- ローカル環境 (Local Environment)
	- **用途**: 各開発者が個別に使用する環境です
	- **タイミング**: 各開発者が自由にローカルブランチを切り替えます
- 開発環境 (Local Environment)
	- **用途**: チーム全体での開発作業を行うための共有環境です。ローカルで開発された機能を統合し、全体の動作確認を行います。コードレビューを行ったり、CIを実行する環境として使われたりします。チームで取り合いにならないようにチーム数の数だけ環境があると良いです
	- **タイミング**: `develop` ブランチにマージされたタイミングで自動デプロイします。また、`feature` ブランチを一時的にデプロイする場合もあります
- 評価環境 (Testing/QA Environment)
	- **用途**: テスト担当者が機能の動作確認やバグの検出を行う環境です。統合テスト、システムテストなどが行われます
	- **タイミング**: `main` ブランチにマージされたタイミングで自動デプロイします
- ステージング環境
	- **用途**: 本番リリース前の最終確認を行う環境です。ここでは実際の本番環境に極めて近い設定(データ件数等も揃えるため本番データを個人情報部分をマスキングして本番になるべく合わせる)で、リリースするコードが問題ないかの最終確認をします。ステークホルダーによる承認や、受け入れテストもここで行います
	- **タイミング**: GitHubのリリース機能の `pre-release` のタイミングで自動デプロイ
- 本番環境
	- **用途**: 本番環境！
	- **タイミング**: GitHubのリリース機能の `release` のタイミングで自動デプロイ

こんな感じの環境が理想なのですが、これだけの環境を用意するにはそれなりの規模、それなりの予算がある案件でないと実現難しそうです。これまでは本番環境しかない案件もありましたし、開発環境が5つも用意されている潤沢な案件もありました。

## コラム: Gitクライアントツールは何を使うのがいい？

Gitクライアントツールは何を使いますか？
コマンド(CUI)、TUI(ターミナル)、画面(GUI)。

これは個人の話なので好きなものを使えばいいと思います。

私はCUIと[lazygit](https://github.com/jesseduffield/lazygit) というTUIを併用しています。
CUIだとファイル差分を確認したり、部分的にステージングしたい時に不便なのでステージングの上げ下げする時にTUIを使っています。

CUIを使うメリットとしては、他の人に共有したり説明しやすいからです。
また、GUIをインストールできない環境もあるので普段からコマンドに慣れておきたいというのもあります。

Gitクライアントツールはたくさんあるのでお気に入りのツールを見つけましょう。
https://git-scm.com/downloads/guis

GUIだと[GitUp](https://gitup.co)とか好きです。

## コラム: マージとリベースはどちらを使うのがいい？

結論: どちらも使うので使い分けが必要です。
マージとリベースの説明は省きます。

マージのデメリットとしてはコミット履歴が時系列通りに並ぶため、複数のブランチがマージされた後に履歴を遡ると読みづらい。
リベースのデメリットとしてはコミット履歴が書き換わるので、複数人が触るブランチでは使用できない。

リベースは個人の作業ブランチのみで利用し、マージはそれ以外の時に利用する。
個人の作業ブランチにマージコミットが増えると読みづらいため。

リベースを行うタイミングとしては次の2回で良いと思います。

- Pull Requestを作成してレビュー依頼を行う前
- Pull Requestのレビューが完了(Approveもらった後)し、マージする前
	- Approve後のリベースはチームの運用によっては許可されない場合もある

レビュー途中にリベースは行わないこと。コミット履歴が変更されるとレビュワーが困るため。こうしてマージするとコミットがきれいに並ぶため、コミット履歴を追いやすくなります。

## コラム: GitHubのマージボタンはどれを使うべき？

Pull Requestのマージは3種類あります。
https://docs.github.com/ja/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/merging-a-pull-request

- `Create a merge commit`
	- マージコミットが作られる
	- コミットはそのまま
- `Squash and merge`
	- マージコミットは作られない
	- コミットが1つにまとめられる
- `Rebase and merge`
	- マージコミットは作られない
	- コミットはそのまま

`Create a merge commit`  ボタンで良いと思ってます。
マージコミットがあるとPR単位で `revert` しやすいからです。

`Squash and merge` 
コミットが一つにまとめられると、まとめる前の状態に戻せないところが注意点ですね。
コミットが一つなため、 `revert` しやすい利点はある。
[Squash コンフリクト](https://tech.mobilefactory.jp/entry/2023/11/29/160000) 問題も起こる。

`Rebase and merge`
マージコミットがないため、PR単位での `revert` が難しくなる。
コミット履歴が綺麗になるメリットはあるが、デメリットの方が大きいので選択しなくて良さそう。

## さいごに

ブランチ戦略は何を使用すればいいのか？
機能フラグの導入や、しっかりしたCI/CDを組み、開発スピードに重きを置くのであれば Trunk Based Development なのかなと思います。

次におすすめするのはGitHub Flowです。シンプルなのが良いですね。
その後、開発進んでデプロイ環境が増えてきたらGitLab Flowに移行すると良いと思います。

大規模な開発だったりリリース管理が重要なプロジェクトであればGit Flowをおすすめします。