gitで一旦取り消しRevertをしたら、RevertのRevertをすべし


いろんなプロジェクトを渡り鳥していると、「間違ってmaster/developにマージしちゃいました」案件がちょいちょいあります。
その場合、基本的にはmaster/developでgitのRevertをして対応してました。
でも、その後RevertのRevertをするのが漏れてしまうパターンがよくあります。

RevertのRevertが必要だと分かっていて漏れてしまうのは仕方ないのですが、
以前手伝っていたプロジェクトで「え?なんで必要なの?」っていう人がいたのを思い出したので記事にしてみました。


まずこんなソースがmasterブランチにあったとします。
元ソース

ここで$hogeだけでなく$foooという値も返せるようにしたくなったとします。
ブランチ「feature/fooo」を切って修正し、masterにマージします。
元ソース

ここで、$foooを返すメソッドを作ってなかったことに気づき、masterでrevertします。
元ソース

「feature/fooo」にメソッドを追加し、masterにマージします。
クラス変数やコンストラクタの処理が残っているように見えます。
元ソース
※なお、ここでコンフリクトは起きていません。

できあがったソースがこちらです。
最後に追加したメソッドのみが追加されており、クラス変数やコンストラクタの処理は入っていません。
元ソース

これだと想定した挙動になりませんね。


勘違いされる要素として、Revertは「対象コミットを取り消す」処理だと思っている人がたまにいます。
Revertはコミットを取り消すのではなく「対象コミットを打ち消すような修正コミットを新たに発行する」処理です。
Revert対象のコミットが無かったことになっている訳ではありません。

なので、Revertコミットはそれを更にRevertしないと、Revertコミットの修正が残ってしまいます。

手順をまとめると以下のようになります。

ダメなパターン

  1. 作業ブランチからmasterにマージする。
  2. masterでリバートする。
  3. 作業ブランチで修正を続ける。
  4. 作業ブランチからmasterにマージする。

良いなパターン

  1. 作業ブランチからmasterにマージする。
  2. masterでリバートする。
  3. 作業ブランチにmasterをマージする。(ダメなパターンで漏れてる)
  4. 作業ブランチでRevertをRevertする。(ダメなパターンで漏れてる)
  5. 作業ブランチで修正を続ける。
  6. 作業ブランチからmasterにマージする。

という訳でRevertした修正を捨てる訳でなければRevertのRevertをしましょう。