先に結論(という名の戒め)
- こまめにローカルブランチとリモートブランチを同期しましょう
- 特に、PR/MR の suggested changes を適用した時は必ずその修正をローカルに反映しましょう
-
force push
は歴史の改変なのだということを強く意識しましょう
事の発端
〜とある MR1 のレビュー中〜
私「そろそろこの MR も終わりに近づいてきたなあ。他の人の MR がマージされて develop ブランチが先に進んだようだし、develop ブランチのコミットを取り込むか」
私「コミットの履歴は1本にしたいし、rebase でやろう。git fetch
でリモートの状態を手元に取り込んで、git rebase origin/develop
っと。」
私「お、コンフリクトした。いい感じに修正して・・・このままだと push で弾かれるから、git push origin branch1 -f
でリモートに反映!」
私「@レビュワーのみなさま
develop ブランチの修正を取り込み、コンフリクトを解消しました。ご確認お願いします 」
私「色々と戻ってる・・・???そんなはずは・・・」
私(コードを確認)
私「ほんとに戻っちゃってる・・・・ なんで・・・???」
時系列の整理
- 私、MR を出す
- いくつか修正コメントをいただいたので修正して push
- suggested change に書くには多すぎる量の修正提案があったので、レビュワーが修正案を別の MR として作成
- このとき、作成いただいた MR のマージ先ブランチは元の MR の source branch
- レビュワーが作成した MR をマージ
- この間に、別のメンバーが進めていた MR が develop ブランチにマージされる
-
git fetch
して最新の状態をローカルに取得後、git rebase origin/develop
で別メンバーの修正を自分のブランチに取り込み - コンフリクトしていたのでローカルで修正
-
git push -f
でリモートに反映 - レビュワーからのコメントで巻き戻りに気づく
何が悪かったのか??
やらかしの原因は、ここ。
↓ ↓ ↓ ↓ ↓ ↓ ↓
git fetch
して最新の状態をローカルに取得後、git rebase origin/develop
でマージされた修正を自分のブランチに取り込み
↑ ↑ ↑ ↑ ↑ ↑ ↑
もうちょっと詳しく
時系列 1〜4 の時点で、私のローカルの作業ブランチは MR の source branch(= ローカルの作業ブランチをリモートに push したもの)よりも遅れている状態になっていました。
その後、時系列 5〜7 で MR の source branch(= ローカルの作業ブランチをリモートに push したもの)に入った修正をローカルの作業ブランチに取り込まないまま、作業ブランチを force push してしまった ために、MR 上で修正が巻き戻った状態になってしまいました。
本当はどうすべきだった?
時系列 4 の後すぐに、MR の source branch の修正をローカルの作業ブランチに取り込むべきでした。
結論という名の戒め、再掲
- こまめにローカルブランチとリモートブランチを同期しましょう
- 特に、PR/MR の suggested changes を適用した時は必ずその修正をローカルに反映しましょう
-
force push
は歴史の改変なのだということを強く意識しましょう- force push に慣れちゃうとなんかあったら脳死で
-f
つけちゃうの、ほんと良くない
- force push に慣れちゃうとなんかあったら脳死で
-
現在関わっているプロジェクトでは GitLab を利用しています。MR = Merge Request です。GitHub の PR(Pull Request)とほぼ同じです。 ↩