お問い合わせ

【Git入門】コンフリクトとは?発生原因・マーカーの読み方・解消手順を図解

前回の「Git実践・応用編」では、スタッシュ、リベース、スカッシュマージ、リバートなど、実務で役立つ操作を学びました。本記事では、複数人での開発でよく遭遇するGitのコンフリクトについて解説します。コンフリクトが起きる仕組みから、マーカーの読み方、解消の手順までを図で確認していきましょう。

https://youtu.be/dazRkaBBXXI

シリーズの全体像

このGit学習シリーズは、全部で4つの章に分かれています。

  1. 基礎編:Gitの考え方
  2. 基本操作編:毎日使う操作
  3. 実践・応用編:実務で使う操作
  4. コンフリクト編:競合への対応

第1章ではGitの考え方を、第2章では毎日使う基本操作を、第3章では実務で役立つ操作を学びました。本記事では、最終章となる第4章の「コンフリクト編」として、競合への対応を学びます。

コンフリクトとは

コンフリクトとは、Gitが変更を自動で統合できず、人の判断が必要になっている状態のことです。日本語では「競合」と呼ばれます。

コンフリクトは、エラーや故障ではありません。Gitが「どちらの変更を採用すればよいか判断できないので、決めてください」と、人に判断を求めています。

つまり、コンフリクトは「Gitからの相談ごと」と考えるとイメージしやすくなります。

コンフリクトが起きる原因

コンフリクトが起きる典型的な例は、同じファイルの同じ行を、それぞれのブランチで別の内容に変更したケースです。

図では、main ブランチ側と作業ブランチ側で、greeting.txt の2行目を次のように変更しています。

  • main ブランチ側:Hello, World
  • 作業ブランチ側:Hello, Everyone

同じ2行目に対して、2つの異なる変更が行われています。

マージでコンフリクトが発生する流れ

この2つのブランチをマージすると、Gitは変更を自動で統合しようとします。しかし、同じ行に Hello, WorldHello, Everyone という異なる変更があるため、どちらを採用すべきか判断できません。

そこでGitは、勝手にどちらかを選ばず、コンフリクトという形で人に判断を委ねます。

コンフリクトマーカーの読み方

コンフリクトが起きると、Gitは競合している場所に「コンフリクトマーカー」と呼ばれる目印を書き込みます。

おはよう
<<<<<<< HEAD
Hello, World
=======
Hello, Everyone
>>>>>>> feature
またね

今回のマージでは、<<<<<<< HEAD から ======= までが、いまのブランチ側の内容です。======= から >>>>>>> feature までが、取り込もうとしたブランチ側の内容です。

Gitは両方の内容を並べることで、どちらを残すか判断するように伝えています。コンフリクトマーカーは壊れた表示ではありません。

コンフリクトを解消する4つのステップ

マージで発生したコンフリクトは、次の4つのステップで解消します。

  1. 残す内容を判断する
    どちらの変更を残すかを決めます。必要であれば、両方の変更を組み合わせることもあります。
  2. ファイルを修正する
    判断した内容に合わせてファイルを修正し、コンフリクトマーカーを削除します。
  3. add を実行する
    修正したファイルを add して、このファイルのコンフリクトを解消したことをGitに伝えます。
  4. commit を実行する
    commit すると、マージが完了します。

第2章で学んだ addcommit は、コンフリクトの解消でも使います。基本操作の延長として流れを覚えておきましょう。

mergeとrebaseで発生するコンフリクトの違い

コンフリクトは、merge のときだけでなく、第3章で学んだ rebase のときにも発生します。

  • merge の場合
    発生したコンフリクトをまとめて解消し、最後に commit して統合を完了します。
  • rebase の場合
    コミットを1つずつ積み直すため、その途中でコンフリクトが複数回起きることがあります。コンフリクトを解消して add したあと、rebase --continue で処理を続けます。

どちらの場合も、内容を判断し、ファイルを修正して add するまでの基本的な対応は同じです。

コンフリクトは怖くない

コンフリクトを怖がる必要がない理由は、次の3つです。

  1. Gitが壊れたわけではない
    勝手に統合せず、人の判断を待っているGitの正常な動作です。データが消えたわけでもありません。
  2. どの変更を採用するか決めればよい
    コンフリクトはGitからの相談ごとです。内容を確認して、残す変更を決めます。
  3. 原因と手順を知っていれば対応できる
    「判断、修正、add」が、コンフリクトを解消するときの基本の流れです。

最初は戸惑うかもしれませんが、仕組みと手順が分かっていれば落ち着いて対応できます。

まとめ

コンフリクトは、Gitが壊れた状態ではなく、人の判断が必要になっている正常な状態です。エラーや故障ではなく、「どの変更を採用するか決めてください」というGitからの相談ごとです。

対応の流れは、次のとおりです。

  1. 残す内容を判断する
  2. ファイルを正しい形に修正する
  3. add で解消したことをGitに伝える
  4. commit または rebase --continue で統合を完了する

コンフリクトが起きたときは、まず競合している内容を確認し、この流れに沿って対応しましょう。