はじめに
これまで、システム責任者がfeatureブランチの作成・削除を行っていました。
しかし、開発者が増えてくると、
- featureブランチを作るたびに責任者へ依頼する
- 開発完了後のブランチ削除も責任者が行う
- developへの反映方法が人によって異なる
といった運用上の負担が大きくなります。
そこで、以下のような運用へ変更します。
main
↑
│ Pull Request
│
develop
↑
│ Pull Request
│
feature/*
基本方針は以下です。
- 開発者自身が
developからfeatureブランチを作成する - featureブランチ上で開発する
- 開発完了後、Pull Requestで
developへ反映する - Merge後はfeatureブランチを削除する
-
developとmainには原則直接pushしない
本記事では、この一連の流れをまとめます。
想定するブランチ構成
今回は以下のような構成を想定します。
main
develop
feature/*
役割は以下です。
| ブランチ | 用途 |
|---|---|
main |
本番環境へリリースするコード |
develop |
STG環境などで統合テストするコード |
feature/* |
機能単位の開発用ブランチ |
例えば「ユーザー検索機能」を開発する場合、
feature/user-search
というブランチを作成します。
1. 最新のdevelopを取得する
featureブランチは、原則として最新の develop から作成します。
まず develop ブランチへ移動します。
git switch develop
GitHub上の最新状態を取得します。
git pull origin develop
これでローカルの develop が最新になります。
2. featureブランチを作成する
最新のdevelopからfeatureブランチを作成します。
git switch -c feature/user-search
この時点ではローカルPC上にだけfeatureブランチが存在しています。
イメージとしては以下です。
develop
|
+--- feature/user-search
3. GitHubへfeatureブランチをpushする
作成したfeatureブランチをGitHubにも作成します。
git push -u origin feature/user-search
-u は、ローカルブランチとGitHub上のブランチを紐付けるオプションです。
最初の1回だけ実行すれば、それ以降は、
git push
だけでpushできます。
4. featureブランチ上で開発する
featureブランチ上では通常通り開発します。
git status
git add .
git commit -m "ユーザー検索機能を追加"
git push
複数回コミットしても問題ありません。
例えば、
develop
A---B---C
\
D---E---F
feature/user-search
という形になります。
この段階では、featureブランチの変更はまだdevelopには入っていません。
5. 開発中にdevelopの最新変更を取り込む
featureブランチで開発している間に、他の開発者の変更がdevelopへMergeされることがあります。
その場合、自分のfeatureブランチへ最新のdevelopを取り込みます。
まずdevelopを最新化します。
git switch develop
git pull origin develop
続いてfeatureブランチへ戻ります。
git switch feature/user-search
developの変更を取り込みます。
git merge develop
例えば以下の状態だったとします。
develop
A---B---C---D
\
E---F
feature/user-search
git merge develop を実行すると、
develop
A---B---C---D
\ \
E---F---M
feature/user-search
となり、develop側の最新変更がfeatureへ取り込まれます。
最後にGitHubへpushします。
git push
developへ移動せずに取り込む方法
featureブランチにいる状態から直接最新のdevelopを取り込むこともできます。
git fetch origin
git merge origin/develop
つまり、
git switch feature/user-search
git fetch origin
git merge origin/develop
git push
でも構いません。
Gitに慣れるまでは、
git switch develop
git pull origin develop
git switch feature/user-search
git merge develop
のほうが処理内容を理解しやすいと思います。
コンフリクトが発生した場合
featureとdevelopで同じ箇所を変更している場合、Merge時にコンフリクトが発生することがあります。
例えば、
CONFLICT (content): Merge conflict in ...
Automatic merge failed; fix conflicts and then commit the result.
のようなメッセージが表示されます。
その場合は対象ファイルを修正します。
修正後、
git add .
Merge結果をコミットします。
git commit
最後にpushします。
git push
6. 開発完了後にPull Requestを作成する
featureブランチの開発が完了したら、GitHub上でPull Requestを作成します。
今回の設定は、
base: develop
compare: feature/user-search
です。
意味としては、
feature/user-search
↓
develop
となります。
base が取り込み先、
compare が変更元です。
Pull Requestには何を書くか
例えば以下のように記載します。
タイトル
ユーザー検索機能を追加
本文には、
## 対応内容
- ユーザー名による検索を追加
- メールアドレスによる検索を追加
- 検索結果のページングを追加
## 確認内容
- ユーザー名検索
- メールアドレス検索
- 検索結果0件の場合
といった内容を書いておくと分かりやすくなります。
Pull Requestを使うことで、
- 誰が
- いつ
- 何のために
- どのような変更を行ったか
- 誰がレビューしたか
- いつdevelopへ取り込まれたか
といった情報をGitHub上に残せます。
7. Pull RequestをdevelopへMergeする
Pull Requestの内容を確認し、問題がなければGitHub上でMergeします。
feature/user-search
↓
develop
これでfeatureブランチの変更がdevelopへ反映されます。
8. GitHub上のfeatureブランチを削除する
Mergeが完了したfeatureブランチは基本的に削除します。
GitHub上ではMerge後に、
Delete branch
というボタンが表示されるため、そこから削除できます。
featureブランチは作業用の一時ブランチなので、developへ取り込まれた後は残しておく必要はありません。
9. ローカルのfeatureブランチも削除する
GitHub上のブランチを削除しても、開発者PCにはローカルブランチが残っています。
まずdevelopへ戻ります。
git switch develop
最新のdevelopを取得します。
git pull origin develop
featureブランチを削除します。
git branch -d feature/user-search
最後に、GitHub側で削除済みのリモートブランチ情報を整理します。
git fetch --prune
これでfeatureブランチを使った一連の開発は完了です。
開発者が普段実行するコマンド
feature開発開始時は、基本的に以下です。
# developへ移動
git switch develop
# 最新developを取得
git pull origin develop
# featureブランチを作成
git switch -c feature/user-search
# GitHubへpush
git push -u origin feature/user-search
その後、通常通り開発します。
git add .
git commit -m "ユーザー検索機能を追加"
git push
developの最新変更をfeatureへ取り込む場合
git switch develop
git pull origin develop
git switch feature/user-search
git merge develop
git push
開発完了後
GitHub上で、
feature/user-search
↓ Pull Request
develop
を作成します。
Merge後はローカルを整理します。
git switch develop
git pull origin develop
git branch -d feature/user-search
git fetch --prune
developへの直接pushは原則禁止にする
チーム開発では、開発者がdevelopへ直接pushできる状態にするより、
feature
↓
Pull Request
↓
develop
というルールにしたほうが安全です。
つまり以下のような操作は原則行いません。
git switch develop
git push origin develop
代わりにfeatureブランチからPull Requestを作成します。
mainへの反映もPull Requestにする
STGテストが完了した後、本番リリースする場合も同様です。
feature/*
↓
Pull Request
↓
develop
↓
STGテスト
↓
Pull Request
↓
main
↓
本番リリース
Pull Requestは以下の2種類になります。
| 用途 | 変更元 | 変更先 |
|---|---|---|
| 機能開発 | feature/* |
develop |
| 本番リリース | develop |
main |
STGテスト中にバグが見つかった場合
STGテストで不具合が見つかった場合も、developを直接編集するのではなく修正用ブランチを作成すると管理しやすくなります。
例えば、
develop
|
+--- fix/user-search-error
修正後、
fix/user-search-error
↓
Pull Request
↓
develop
とします。
つまり基本ルールとして、
main
develop
は直接変更せず、
feature/*
fix/*
などの作業ブランチを経由します。
おすすめの運用ルール
最終的には以下のようにするとシンプルです。
main
├─ 直接pushしない
└─ developからPull Request
develop
├─ 直接pushしない
└─ feature/fixからPull Request
feature/*
├─ 開発者が作成
├─ 開発者が自由にpush
└─ Merge後に削除
fix/*
├─ 開発者が作成
├─ 開発者が自由にpush
└─ Merge後に削除
全体フロー
最終的な開発フローは以下です。
feature/login
│
│
feature/search
│
↓
Pull Request
│
↓
develop
│
│
STGテスト
│
│
バグがあれば
fix/*
│
↓
Pull Request
│
↓
develop
│
│
Pull Request
│
↓
main
│
↓
本番リリース
まとめ
今回の運用では、
develop
↓
feature作成
↓
開発
↓
Pull Request
↓
developへMerge
↓
feature削除
という流れを開発者自身が行います。
また、開発中にdevelop側で変更があった場合は、
git switch develop
git pull origin develop
git switch feature/xxx
git merge develop
git push
として最新の変更を取り込みます。
Pull Requestを導入することで、単にコードをMergeするだけではなく、
- 変更内容をレビューできる
- 変更理由を記録できる
- 誰がMergeしたか分かる
- develop/mainへの直接pushを防げる
- チーム内で開発フローを統一できる
といったメリットがあります。
特に複数人で開発する場合は、
作業ブランチ
↓
Pull Request
↓
共有ブランチ
という形に統一しておくと、Git/GitHubの運用がかなり整理しやすくなります。