LoginSignup
10

More than 3 years have passed since last update.

gitでrevertしたら再revertが必要な例とその理由

Posted at

[https://qiita.com/taisa831/items/c17ce15818b9f8fa26b8:title]

こちらの記事を読んで、「何が起きるか」はわかったけど「なぜこうなるか」がすぐに分からなかったのでメモ。

具体例

以下の例を考える。

  • masterブランチからdevブランチを切った。
  • devブランチでb.txtを追加してコミットを積んだ。
  • masterブランチでc.txtを追加してコミットを積んだ。
  • masterブランチにdevブランチをマージした。
  • devブランチでの変更点に不具合があったことが判明し、masterでdevのマージコミットをrevertした。
* 6589fe9 (HEAD -> master) Revert "Merge branch 'dev'"
*   c7e7528 Merge branch 'dev'
|\
| * 30f185a (dev) added b.txt
* | 5169671 added c.txt
|/
* 18f28e9 added a.txt

問題が発生するパターン

  • devブランチにパッチを当てて(d.txtを追加して)コミットを積んだ
  • devブランチを再度masterにマージした
*   436c043 (HEAD -> master) Merge branch 'dev'
|\
| * ddf8924 (dev) added d.txt  # commit 1
* | 6589fe9 Revert "Merge branch 'dev'"  # commit 2
* |   c7e7528 Merge branch 'dev'
|\ \
| |/
| * 30f185a added b.txt  # commit 3
* | 5169671 added c.txt
|/
* 18f28e9 added a.txt

ここでマージ後のmasterがどうなっているかというと…

% git checkout master
% ls
a.txt   c.txt   d.txt

当初devブランチで追加したb.txtが見当たらない。

問題が発生する理由

  • 上記のcommit 1とcommit 2をマージするときに、マージベースはcommit 3となる。
  • commit 3からcommit 1にかけての差分は「d.txtを追加した」こと
  • commit 3からcommit 2にかけての差分は「なし」(b.txtが追加され、削除された)
  • commit 3ではa.txt, b.txtが存在したので、それに上記2つの差分を足して実現するのは、a.txt, b.txt, d.txtが存在する状態

問題を回避するやり方

いずれにせよrevert以前の内容が必要なら、revertをrevertすべし。

devブランチをそのまま伸ばす
  • devブランチにmasterをマージする
  • devブランチでrevertをrevertする
  • devブランチにパッチを当てて(d.txtを追加して)コミットを積む
  • devブランチを再度masterにマージする
*   3a746ec (HEAD -> master) Merge branch 'dev'
|\
| * e3cf889 (dev) added d.txt
| * 498e552 Revert "Revert "Merge branch 'dev'""
| *   c440eb6 Merge branch 'master' into dev
| |\
| |/
|/|
* | 6589fe9 Revert "Merge branch 'dev'"
* |   c7e7528 Merge branch 'dev'
|\ \
| |/
| * 30f185a added b.txt
* | 5169671 added c.txt
|/
* 18f28e9 added a.txt

こうすれば、当初devブランチで作成したb.txtも最終的にmasterブランチに残る。

% git checkout master
% ls
a.txt   b.txt   c.txt   d.txt
ブランチを切り直す
  • masterブランチからdev2ブランチを切り直す
  • dev2ブランチでrevertをrevertする
  • dev2ブランチにパッチを当てて(d.txtを追加して)コミットを積む
  • dev2ブランチをmasterにマージする
*   ea16e7a (HEAD -> master) Merge branch 'dev2'
|\
| * a87d323 (dev2) added d.txt
| * 98c5d6f Revert "Revert "Merge branch 'dev'""
|/
* 6589fe9 Revert "Merge branch 'dev'"
*   c7e7528 Merge branch 'dev'
|\
| * 30f185a (dev) added b.txt
* | 5169671 added c.txt
|/
* 18f28e9 added a.txt

この方法でも、当初devブランチで作成したb.txtが最終的にmasterブランチに残る。

% git checkout master
% ls
a.txt   b.txt   c.txt   d.txt

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10