はじめに
最近、PR(プルリクエスト)を適切な粒度に分割することを考えるようになりました。
ただ、その場合バックマージをすることが多くなると思い、バックマージの不安点を練習してみた。
想定ブランチ構成
・develop
・feature/test1-A
・feature/test1-B
シチュエーション
test1という機能を追加したい。
とはいえ、test1という機能は大きく、A機能とB機能があり1つのPRだと大量の変更になってしまう。
しかも、厄介なことにA機能とB機能で改修するクラスがかぶっている。
レビューがしやすい様に、A機能とB機能のPRを分割。
とはいえ、レビューを直列にすると2倍の期間になってしまう。
ので、A機能とB機能のPRを並行して依頼を出す。
やりたきことの流れ
1.developブランチから、feature/test1-A を作成し、PR(test1-A → develop)を出す。
2.更に並行して、feature/test1-A から feature/test1-Bを作成し、PR(test1-B → test1-A)を出す。
3.test1-AのPRレビューが完了後、developへマージ。
4.test1-BのPRレビューが完了後、マージ先を developに変更してマージ。
不安な点
test1-AのPRレビュー時に修正が発生した場合は、test1-Bにバックマージを行う必要があるが、バックマージに不慣れなのでドキドキ。
バックマージのやり方
その1
git switch feature/test1-B
git pull origin feature/test1-A
その2
git switch feature/test1-B
git fetch
git merge feature/test1-A
その3
git switch feature/test1-B
git fetch
git merge origin/feature/test1-A
気になっていること
その1とその2は同じ?
を見ると、pullは fetchしてmergeしているようなので同じはず?
その2とその3は同じ?
ローカルブランチからか、リモートブランチからかの違いのはずだから、最新化していれば同じはず?
やってみる。
事前準備
git switch develop
git branch feature/test1-A
git switch feature/test1-A
echo 'A機能の追加' >> test1.txt
git add .
git commit -m 'A機能の追加'
git push origin feature/test1-A
# PR作成
gh pr create
# PR確認
gh pr view --web
git branch feature/test1-B
git switch feature/test1-B
echo 'B機能の追加' >> test1.txt
git add .
git commit -m 'B機能の追加'
git push origin feature/test1-B
# PR作成
gh pr create
# PR確認
gh pr view --web
test1-Aで修正発生
git switch feature/test1-A
vi test1.txt
A機能の追加 → A機能の追加の修正
git add .
git commit -m 'A機能の追加の修正'
git push origin feature/test1-A
test1-Bにバックマージ
git merge feature/test1-A
git switch feature/test1-B
git fetch
git merge feature/test1-A
コンフリクトが発生
vi test1.txt
git add .
git commit
git push origin feature/test1-B
PR上の見え方
コミットコメント
Merge branch 'feature/test1-A' into feature/test1-B
git merge origin/feature/test1-A
※ 一からやり直すのは手間なので、test1-Aで修正発生の手順で、さらに「修正」を付け加えていく。
git switch feature/test1-B
git fetch
git merge origin/feature/test1-A
コンフリクトが発生
vi test1.txt
git add .
git commit
git push origin feature/test1-B
PR上の見え方
コミットコメント
Merge remote-tracking branch 'origin/feature/test1-A' into feature/test1-B
git pull origin feature/test1-A
※ 一からやり直すのは手間なので、test1-Aで修正発生の手順で、さらに「修正」を付け加えていく。
※ fetchしなくてもよいはずだが、なんとなくしてしまった。
git switch feature/test1-B
git fetch
git pull origin feature/test1-A
git push origin feature/test1-B
PR上の見え方
コミットコメント
Merge branch 'feature/test1-A' of https://github.com/tarosuke777/sandbox into feature/test1-B
やり直しコマンド
git switch develop
git branch -D feature/test1-A
git branch -D feature/test1-B
git push origin --delete feature/test1-A
git push origin --delete feature/test1-B
個人的結論
どれも、ローカルを最新化していれば一緒の雰囲気。
コミットコメントのマージ元が変わるので、レビュー時にどこからマージしたのかよくわかる。
git pull は楽だけど、せっかくコマンドが分かれているので、git fetch + git merge を使っていこうかな?と思った今日のこの頃。
だいぶマージに慣れてきた気がする。ので、バックマージが苦手な方は、個人で練習してみるのはおすすめです。
おまけ
最終的な樹形図はどうなっているか、気になったので見てみました。
意図通りかなって感じでした。
$ git log --graph --oneline
* 3ef6ba0 (HEAD -> develop, origin/develop) Merge pull request #8 from tarosuke777/feature/test1-B
|\
| * 714c110 (origin/feature/test1-B, feature/test1-B) Merge branch 'feature/test1-A' of https://github.com/tarosuke777/sandbox into feature/test1-B
| |\
| * \ cf65eda Merge remote-tracking branch 'origin/feature/test1-A' into feature/test1-B
| |\ \
| * \ \ ccbe8c2 Merge branch 'feature/test1-A' into feature/test1-B
| |\ \ \
| * | | | 79a8b7e B機能の追加
* | | | | 2052a21 Merge pull request #7 from tarosuke777/feature/test1-A
|\ \ \ \ \
| | |_|_|/
| |/| | |
| * | | | df1ebf6 (origin/feature/test1-A, feature/test1-A) A機能の追加の修正の修正の修正
| | |_|/
| |/| |
| * | | 3ee5d88 A機能の追加の修正の修正
| | |/
| |/|
| * | 2ce5449 A機能の追加の修正
| |/
| * 2be5105 A機能の追加
|/
* 253dbc0 Initial commit
おまけその2