概要
git rebaseで競合したファイルが多い場合、大抵僕はgit checkout --theirsとか--oursで競合解決してます。
ある時職場で、僕が競合修正したファイルに、「以前コミットしたはずの修正が無い」といわれたので、
まさかと思い調査してみたところ--theirsとか--oursを行なって競合修正したことが原因でした。
一見楽そうに見える競合解決方法の--theirsと--oursですが、間違った知識でつかっていると危険なので注意してください。
checkout --theirsと --oursで発生しうる悲劇
1~10までを英語で書いたファイルを作成します。
あえて、2と9を間違って書いてmasterブランチにコミットしておきます。
1 one
2 TOE
3 three
4 four
5 five
6 six
7 seven
8 eight
9 NAINE
10 ten
この時点でfeatureブランチを切っておきます。
そして、masterブランチで2行目のTOEを以下のようにtwoに修正してコミットします。
9行目のNAINEはあえて直さずにおいておきます。
1 one
2 two
3 three
4 four
5 five
6 six
7 seven
8 eight
9 NAINE
10 ten
つぎに、featureブランチに移って、2行目と9行目を修正してコミットします。
あえて2行目で競合が発生するようにtwoではなくtowと修正しました。
1 one
2 tow
3 three
4 four
5 five
6 six
7 seven
8 eight
9 nine
10 ten
git rebase masterとmasterのようにリベースをかけると当然、2行目で競合が発生します。
また、gitのオートマージにより9行目のnineはfeatureで直した単語になっています。
1 one
<<<<<<< 7f8b619dc56865912a9596195faba741938d39c9
2 two
=======
2 tow
>>>>>>> 2と10が間違っていたので修正
3 three
4 four
5 five
6 six
7 seven
8 eight
9 nine
10 ten
ここで、masterの変更が正しいからと言ってgit checkout --oursとしてしまうと悲劇が始まります。
$ git checkout --ours .
$ cat test
1 one
2 two
3 three
4 four
5 five
6 six
7 seven
8 eight
9 NAINE
10 ten
9行目は先ほどfeatureで直した値になっていて欲しいのですが、masterに一致されています。
当然ですが、featureに一致させるために--thirsしても以下のように間違った修正になってしまいます。
$ git checkout --theirs .
$ cat test
1 one
2 tow
3 three
4 four
5 five
6 six
7 seven
8 eight
9 nine
10 ten
git checkout は指定したファイルを指定したコミットに一致させることになるので、
せっかくgitがオートマージしてくれてもその心遣いを完全に無視してリベース元なり、リベース先なりのブランチの変更に合わせてしまいます。
まとめ
横着してgit checkout --theirsとか--oursして競合解決するのではなく、面倒ですが手作業で解決しようと思います。
いい方法を知っているという方いらっしゃいましたらご教授ください。。。