0
0

revertのrevertで復活させたファイルが別ブランチで復活しない

Posted at

一度revertで削除したファイルをバグがなくなったため復活させることにした。
開発ブランチでrevertのrevertを実施すると問題なくファイルが復活するが、releaseブランチにマージしてもreleaseブランチではファイルが復活していなかった。
開発ブランチにあるファイルがマージで反映されない事態に違和感を覚えたため調査した。

以下revertのrevertは長いのでreapplyと呼ぶ。

再現コード

簡略化したコードは下記。

echo "hello, world" > file
git add file
git commit -am "add file"

git branch dst
git revert <add fileしたcommit> --no-edit

git switch dst
git cherry-pick <revertしたcommit>

git switch src
# revertのrevert
git revert <revertしたcommit> --no-edit

git switch dst
git merge src
# fileが存在しない

最新のdstのgit logの結果を見てみると以下の2つの歴史をマージしている

  1. revertしてreapplyしたブランチ(src)
  2. revertしたブランチ(dst)
% git log
commit 900dd818dee2762ad842428d75125e158177ad08 (HEAD -> dst)
Merge: 63f39e5 54c0ecd
Author: myoan
Date:   Thu Sep 19 08:55:38 2024 +0900

    Merge branch 'src' into dst       

commit 54c0ecd0ef0c9c0fa0b6a003e740698b53e83961 (src)
Author: myoan
Date:   Thu Sep 19 08:54:49 2024 +0900               

    Reapply "add file"                               

    This reverts commit 0ac88a74c84d2822d1592b42dee42e526ec1250e.

commit 63f39e5ba70fe038863ac887ccb974e8e6428f23 
Author: myoan
Date:   Thu Sep 19 08:05:23 2024 +0900          

    Revert "add file"                           

    This reverts commit 7e7eb9b6a126469407af3715433bb775179a4567.

commit 0ac88a74c84d2822d1592b42dee42e526ec1250e
Author: myoan
Date:   Thu Sep 19 08:05:23 2024 +0900        

    Revert "add file"                         

    This reverts commit 7e7eb9b6a126469407af3715433bb775179a4567.

commit 7e7eb9b6a126469407af3715433bb775179a4567
Author: myoan
Date:   Thu Sep 19 08:04:36 2024 +0900      
                                            
    add file

3-way mergeで考えるとsrcブランチはrevertとreapplyをしているため実質base commitとの差分がない。
対してdstはrevertしてるためファイルが削除されている。
そのためマージしてもファイルが削除された(=復活していないように見えた)。

今回はrevertやcherry-pickを題材にいているが本件に関係はなく、単純なファイル追加・削除でも再現する。
問題の本質はmergeのタイミングでbaseとHEAD, baseとMERGE_HEADそれぞれのdiffが思い描けてなかったことにある。

対策

もしも発生してしまったら、該当ファイルを削除してdstにマージ、ファイルを復活させてdstにマージ。とするのが簡単か?

個人開発ならともかく、チーム開発しているとdiffを思い描くなんて無理な話である。
ブランチ戦略を変えずに防止・検知する仕組みも考える。

すぐ思いつくのはcherry-pickをした後に srcがdstをマージすることである。
(2つのブランチの歴史が異なるほど安全とは言えないかもしれない)
その上でreapplyをすれば、dstがsrcをマージしてもfileが追加される。
他にはsrc, dstのdiffを定期的に取って確認をすることも有用そう。

0
0
0

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
0
0