はじめに
現職で同僚がステージング環境の1つ前の環境にマージして、コンフリクトが発生しました。そのコンフリクトの解消に誤りがあったものの、気づかずにpushしてしまい、CircleCIで異常終了してしまったことで、コンフリクトの解消法に誤りがあったことが発覚しました。その際にどのように解決したら良かったのかを考えてみました。
解決策の候補
私が思いついた方法は以下3つでした。1つずつ方法を検証していきます。
git revert -m 1 <commitID>
-
git reset --soft <commitID>
を実行後にgit push -f
- マージ先のプログラムを直接修正
git revert -m 1 <commitID>
この解決策の特徴は以下です。
-
マージを取り消したことがログとして残ります。
-
マージを取り消した後に、同じリポジトリを再度マージしてもマージを取り消したプログラムは反映されません。
今回のケースですと、コンフリクトの解消が誤っていたため、再度同じプログラムをマージ先に反映できないと困るため、今回の対応策としては適していないのかと思いました。
git reset --soft <commitID>
を実行後にgit push -f
この解決策の特徴は以下です。
-
マージを取り消した後に、同じリポジトリを再度マージしてもマージを取り消したプログラムは反映されます。
-
マージを取り消したことはログには残りません。
-
pushする際には強制pushしなければいけないため、他の開発メンバーの作業に影響を与える可能性があることです。開発ブログによると、強制pushの注意点として以下のように記載されております。
強制 push は、自分ひとりで作業しているブランチでは、それほど問題にならないでしょう。一方で、チームで開発を行っているとき、共有されたブランチを強制更新するときは注意が必要です。
もし上書きにより、消されてしまったコミットを起点にして、チームメンバーがローカルで開発を進めていたとすると、そのようなメンバーが次回の push で必ず競合が発生してしまうだけでなく、すでに存在しない状態をベースに機能開発を進めてしまうため、すべての前提が崩れてしまう可能性さえあります。
チームメンバーが多いほど、このような問題は発生しやすいのではないでしょうか。共有されたブランチはできるだけ、強制上書きは避けるべきでしょう。
- マージを取り消して、再度マージするため、作業時間が「マージ先のプログラムを直接修正」よりもかかってしまうと思います。
今回のケースですと、マージを取り消して再度マージすることは可能性ですが、強制pushをしなければいけないため、他のメンバーへの作業影響を考えるとリスクが高いため、適していないのかと思いました。
マージ先のプログラムを直接修正後にgit push
この解決策の特徴は以下です。
-
修正したことがログに残ります。
-
強制push(
git push -f
)をしなくてもリモートブランチに反映できるため、他メンバーの作業に影響を与えません。 -
マージを取り消して、再度マージする必要がないため、作業時間が
git reset
よりも短いと思われます。
今回のケースですとgit revert
とgit reset
よりも適した方法なのかと思いました。
最後に
今回記事を書いてみることで、コマンドそれぞれの特徴について理解を深められました。今回自分が考えた方法よりも良い方法をご存知の方がいらっしゃったら、コメントいただけますと幸いです。
参考文献
なおこの記事は以下の情報を参考にして執筆しました。