3秒でわかる
同じ場所への変更がぶつかり、自動では合わせられなくなった状態。Git がどちらを残すか判断できず、人が決めるまで作業を止めて待ちます。
もう少し詳しく
どういうものか
コンフリクトは、2 つの変更を統合しようとしたときに、機械が自動で決められない衝突が起きた状態です。Git では merge や rebase、cherry-pick の途中で発生します。
Git は行単位で差分を見ます。別々の場所を触っただけなら自動で合成されますが、同じ行または隣接する行を双方が書き換えていると、どちらが正しいか判断できません。そこで作業を止め、対象ファイルに両方の内容を印付きで書き込みます。
なぜ必要か
コンフリクトは異常ではなく、安全装置です。もし Git が勝手に片方を選んでいたら、誰かの修正が予告なく消え、しかもコミット履歴上は正常に見えます。バグの原因としては最悪の部類です。
止まってくれるおかげで、両方の意図を確認して正しい形を決められます。
具体例
衝突したファイルは次のようになります。
<<<<<<< HEAD
const TAX_RATE = 0.10;
=======
const TAX_RATE = 0.08;
>>>>>>> feature/tax-update<<<<<<< から ======= までが自分の側、そこから >>>>>>> までが取り込もうとしている側です。印を含めて手で書き直し、正しい 1 つの形にしてから解決を伝えます。
git status # 衝突しているファイルを確認する
# エディタで修正し、印の行を消す
git add src/price.js
git commit # merge の場合
git rebase --continue # rebase の場合やり直したくなったら git merge --abort で手前の状態へ戻せます。
つまずきやすいところ
印の行を消し忘れたままコミットする事故がいちばん多いです。<<<<<<< が残っていればまず動かないので、解決後に該当文字列を検索して確認します。
「自分の変更を全部採用」で片付けるのも危険です。相手が直したバグ修正まで消えることがあります。両方の意図を読み、必要なら両方を残した形に書き直します。
そもそも衝突を減らす手もあります。作業ブランチを長く放置せず、こまめに main を取り込むと、1 回あたりの差分が小さくなり衝突も小さくなります。自動整形の設定がメンバーで揃っていないと、無関係な行まで差分になって衝突の種になります。
自動生成されるファイルも厄介です。ロックファイルやビルド成果物は全行が書き換わるため、手で直す意味がありません。生成し直して置き換えるか、そもそも管理対象から外します。
解決後は必ず動かして確認します。両方の変更を機械的に残しただけでは、構文は通っても意図として矛盾していることがあります。
覚え方
「Git が困って人に投げてきた状態」。責める相手はいません。
