コンフリクト
master にいる状態で feature/add をマージします。
$ git merge feature/add
Auto-merging a.txt
CONFLICT (content): Merge conflict in a.txt
Automatic merge failed; fix conflicts and then commit the result.
またコンフリクトですか、もう疲れてしまいましたね。まとめてコマンド一発でできればいいのですが。
一発で解決出来る場合
a.txtのそれぞれの状態は以下だったとしましょう
1
2
3
1
2
3
4
1
2
3
5000000000000000
コンフリクトしたので、a.txtは今このような状態になっています。
1
2
3
<<<<<<< HEAD
4
=======
5000000000000000
>>>>>>> feature/add
今回はまだ生ぬるいですが、コンフリクトが深刻であるほど、その修復のための作業量は膨大になります。時間というのは有限な資源です。コマンド一発で解決できれば、スターバックスでコーヒーを飲む作業に時間を当てられるわけです。今日はそのスターバックスへの行き方を紹介しましょう。
$ git checkout --ours a.txt
$ git checkout --theirs a.txt
git checkout のオプションに --ours を指定することで、指定したファイルの状態を元々チェックアウトしていたブランチの状態と同じにします。今回で言えば a.txt を master の最新と同じ状態にします。--theirs はその反対、git merge で指定したブランチ側にファイルの状態を同じにします。今回は feature/add ですね。
またこのオプションはコンフリクトしているファイルに対し有効です。したがって次のようなコマンドで、コンフリクトした全てのファイルを、どちらかのブランチの状態の状態に上書きすることが出来ます。
$ git checkout --ours .
一発で解決出来ない場合
例を出しましょう。
1
2
3
4
5
1
1.5
2
3
4
5
6
1
2
3
3.5
4
5
5000000000000000
そしてコンフリクトしている a.txt の状態はこちら
1
1.5
2
3
3.5
4
5
<<<<<<< HEAD
6
=======
5000000000000000
>>>>>>> feature/add
a.txt の特徴として「コンフリクトした部分」と「コンフリクトせずマージ出来た部分」が存在しています。このような状態で git checkout を行ってコンフリクトを解決することは極めて危険です。選択されなかったブランチの「コンフリクトせずマージ出来た部分」が消失してしまうためです。今回の場合 git checkout --ours では 3.5 が、git checkout --theirs では 1.5 が消失します。
git checkout --ours によって削除されるコードは git diff --ours で確認出来ます。ここでコンフリクトの範囲外に存在している行がある場合は、checkout の使用を控えることを強くおすすめします。theirs オプションも同様に git diff --theirs で確認出来ます。
$ git diff --ours
@@ -2,6 +2,11 @@
1.5
2
3
+3.5
4
5
+<<<<<<< HEAD
6
+=======
+5000000000000000
+>>>>>>> feature/add
$ git diff --theirs
@@ -1,7 +1,12 @@
1
+1.5
2
3
3.5
4
5
+<<<<<<< HEAD
+6
+=======
5000000000000000
+>>>>>>> feature/add
大変素晴らしい。私は怖いので手作業でやります。
参考文献
Git - git-checkout Documentation
https://www.git-scm.com/docs/git-checkout#Documentation/git-checkout.txt---ours
Git - git-diff Documentation
https://www.git-scm.com/docs/git-diff#Documentation/git-diff.txt--2--ours