← PC・IT用語集へ戻る

コンフリクト

Conflict
version-control beginner
Gitで変更を統合するとき、同じ箇所に別々の変更が入っていて、どちらを採用するか自動で決められない状態のこと。
コンフリクト (Conflict)

概要(サマリー)

Gitで変更を統合するとき、同じ箇所に別々の変更が入っていて、どちらを採用するか自動で決められない状態のこと。

日本語では「競合」とも呼ばれる。
たとえば、同じファイルの同じ行付近を、別々のブランチや別々の作業者が異なる内容に書き換えていた場合、Gitは「どちらを残せばよいか」を自動判断できないことがある。
この状態がコンフリクトであり、最終的には人間が内容を確認して、どのコードを残すかを決める必要がある。

AIにコードを書き直してもらっている途中で、自分でも同じ場所を修正したり、別ブランチの変更をあとから取り込んだりすると発生しやすい。

詳細解説

コンフリクト(Conflict)とは、Gitで2つ以上の変更を統合しようとしたときに、同じ場所へ別々の修正が入っていて、自動で安全に結合できない状態のことである。

Gitは通常、違う場所への変更ならかなり上手に自動でまとめてくれる。
たとえば、

  • Aさんはヘッダーを修正
  • Bさんはフッターを修正

のように変更箇所が離れていれば、そのまま自動で統合できることが多い。

しかし、

  • Aさんは同じ関数の中身を修正
  • Bさんも同じ関数の同じ行付近を修正

のように、同じ場所に別内容の変更が入ると、Gitは「どちらが正しいか」を判断できない。
そのため、自動統合を止めて人間に判断を求める。
これがコンフリクトである。

なぜコンフリクトが起きるのか

コンフリクトの原因はシンプルで、同じ箇所に複数の変更がぶつかるからである。

よくある例は次の通りである。

1. 別ブランチで同じ行を修正していた

main 側でも変更が入り、作業ブランチ側でも同じ部分を直していた場合。

2. 複数人が同じファイルを触っていた

チーム開発で同じ箇所を別々に編集していた場合。

3. AIの修正と手動修正が重なった

AIに任せた変更と、自分で加えた変更が同じ場所でぶつかった場合。

4. 古いブランチを長く放置した

メインブランチが進んでいるのに、古い状態のブランチで作業を続けていた場合。

つまりコンフリクトは、Gitの不具合ではなく、変更同士が自然にぶつかった結果である。

どんなときに発生するのか

コンフリクトは主に、mergerebase、場合によっては stash の適用 など、変更を重ね合わせる操作のときに発生する。

特に初心者がよく出会うのは次の場面である。

  • main を自分のブランチへ取り込むとき
  • 自分のブランチを mainマージするとき
  • GitHub 上でプルリクエストをマージしようとしたとき
  • AIの修正後に別の変更を重ねたとき

つまり、複数の履歴を1つにまとめようとする場面で起きやすい。

実際にはどう表示されるのか

コンフリクトが起きると、Gitはファイルの中に「競合している範囲」を目印つきで表示することがある。
たとえば次のような形で現れる。

<<<<<<< HEAD
現在のブランチ側の内容
=======
取り込もうとしている側の内容
>>>>>>> feature-branch

この記号は、Gitが「ここで内容がぶつかっています」と教えている印である。

  • <<<<<<< から ======= まで
    片方の内容
  • ======= から >>>>>>> まで
    もう片方の内容

という形になっていることが多い。

この状態ではまだ解決しておらず、そのままでは正常なコードとして動かないことがある。

どうやって解決するのか

コンフリクトは、最終的に人間が中身を見て選ぶ必要がある。

基本的な流れは次のようになる。

  1. コンフリクトしたファイルを開く
  2. ぶつかっている2つの内容を確認する
  3. どちらを残すか、あるいは両方を組み合わせるか決める
  4. コンフリクト用の記号を消して、正しい最終形に直す
  5. 保存して、git add で解決済みとしてGitに伝える
  6. 必要に応じてコミットする

つまり、コンフリクト解消とは
「Gitが決められなかった最終版を、人間が編集して完成させる作業」
である。

なお、マージの途中でいったん中止して元の状態へ戻したい場合は git merge --abort を使う。このオプションを含むマージ関連のコマンドはブランチ開発でよく使うコマンド一覧にまとめている。

コンフリクトを減らすには

完全にゼロにはできないが、減らしやすくする方法はある。

1. ブランチを長く放置しない

長く分かれたままだと、あとで差分が大きくなって衝突しやすい。

2. こまめに同期する

メインブランチの最新変更を適度に取り込む。

3. 役割分担を明確にする

複数人で同じ箇所を同時に触らないようにする。

4. コミットを整理する

何を変えたかを追いやすくすると、解決時の判断もしやすい。

5. AIの修正前後でこまめに確認する

AIが大きく変更した箇所と自分の修正箇所が重ならないか意識する。

AIコーディングとの関係

AIと一緒に開発すると、短時間で大きな変更が入ることが多い。
そのため、自分の手動修正や別ブランチの変更とぶつかりやすくなる。

たとえば、

  • AIに大幅リファクタリングを頼む
  • その間に自分でも同じファイルを修正する
  • あとで統合しようとしてコンフリクトになる

ということは十分ありえる。

このためAIコーディングでは、

  • 修正前にコミットする
  • 作業ブランチを分ける
  • 変更の単位を小さくする
  • こまめに差分を見る

といった進め方がかなり重要になる。

AIにコンフリクト解消を相談するときは、競合している範囲だけでなく、どちらの変更が何を目的としているかも伝えるとよい。
ただし、AIが片方の変更を安易に捨ててしまう可能性もあるため、最終的には差分を読み、必要な処理が残っているか自分で確認することが重要である。

よくある勘違い

コンフリクトはGitの故障?

故障ではない。
同じ場所に別々の変更が入ったため、Gitが安全に自動判断できない状態である。

片方を選べば必ず解決?

必ずではない。
片方だけを残すと、もう一方に含まれていた必要な修正を失うことがある。両方の意図を読み、組み合わせる判断が必要な場合もある。

コンフリクト記号を消せば完了?

記号を消すだけでは不十分である。
最終的なコードが正しく動く形になっているか、必要な変更が残っているかを確認する必要がある。

まとめ

  • コンフリクトは、同じ箇所への複数の変更をGitが自動で統合できない状態である。
  • merge、rebase、stash適用、プルリクエストの統合などで発生することがある。
  • 解決時は、競合範囲を読み、どちらを残すか、両方を組み合わせるかを人間が判断する。
  • AIコーディングでは大きな変更の前後でコミットし、差分を小さく保つと衝突を減らしやすい。

情報ソース

より詳しくAIに聞いてみよう

  • Gitのコンフリクトとは何かを、中学生でもわかるように説明してください。
  • コンフリクトが起きたときの記号 <<<<<<< ======= >>>>>>> の意味を教えてください。
  • コンフリクト解消の基本手順を、初心者向けに順番で説明してください。
  • AIコーディング中にコンフリクトが起きやすい場面を具体例つきで教えてください。
  • コンフリクトを減らすためのブランチ運用を初心者向けに説明してください。