コンフリクトとは?Gitで変更が衝突する仕組みと解消手順・予防設計を実装視点で解説

コンフリクト(マージコンフリクト)とは、同じファイルの同じ箇所を別々のブランチで違う内容に変更したとき、Gitが「どちらを採用すべきか」を自動で決められず統合が止まる状態です。複数人が並行して開発すれば必ず遭遇するもので、慌てて誤った解消をすると他人の変更を消し込んでしまう事故につながります。この記事では、コンフリクトがなぜ起きるのかという仕組みから、コンフリクトマーカーを読んで手作業で直すまでの手順、マージとリベースでの見え方の違い、そして発生そのものを減らす予防設計とチーム運用までを、受託開発の実装視点で順に整理します。

まとめ:コンフリクトは自動統合の衝突であり解消手順と予防設計が実装品質を左右する

先に結論を示します。コンフリクトとは、並行して加えた変更をGitが機械的に統合できない衝突であって、エラーでも障害でもありません。実装で押さえる要点は3つです。第一に、コンフリクトマーカー(<<<<<<<から>>>>>>>まで)を正しく読み、両者の意図を理解したうえで一つの正解に統合すること。片方を機械的に選んで終わらせない。第二に、マージとリベースでは衝突の出方と解消の進め方が変わるため、履歴方針に合わせて操作を選ぶこと。第三に、そもそもの発生を減らす予防──小さく頻繁な統合、明確な担当分担、整形の自動化──を仕組み側で用意すること。解消の速さより、衝突が起きにくい開発フローを設計するほうが、チーム全体の手戻りを減らします。以降で仕組みと判断基準を掘り下げます。

コンフリクトとは何か──Gitが自動でマージできず衝突する仕組みと発生条件

Gitはブランチを統合するとき、共通の祖先コミットを基準にして両方の変更を突き合わせ、重ならない変更は自動で取り込みます。問題になるのは、同じファイルの同じ行(近接する行を含む)を双方が別々に書き換えていた場合です。Gitはどちらの意図が正しいかを判断できないため、その箇所を保留してユーザーに委ねます。これがコンフリクトの実体で、Gitが安全側に倒して止まっている状態だと理解すると落ち着いて対処できます。

衝突が起きるのは行の同時編集だけではありません。片方のブランチでファイルを削除し、もう片方で同じファイルを編集した場合や、同じ名前で別内容のファイルを双方が新規追加した場合も衝突します。逆に、同じファイルでも離れた行の変更どうしなら自動で統合され、コンフリクトにはなりません。つまり「同じファイルを触った」ことが原因なのではなく、「同じ箇所への相反する変更をGitが一つに決められない」ことが原因です。ここを取り違えると、無用にファイル分割へ走るなど誤った予防策を打ちがちです。

発生する変更 Gitの扱い
同じ行を双方が編集 コンフリクト
削除と編集が競合 コンフリクト
離れた行の変更 自動で統合

コンフリクトマーカーの読み方と手作業で解消するまでの基本操作の流れ

マージやプルで衝突が起きると、Gitは処理を中断し、該当ファイルに印を書き込みます。まずgit statusで「both modified」と表示されるファイルを特定するのが出発点です。該当ファイルを開くと、衝突箇所が3つの記号で区切られています。上側が現在のブランチ(HEAD)の内容、区切りの下側が取り込もうとしているブランチの内容です。

<<<<<<< HEAD
const timeout = 3000;
=======
const timeout = 5000;
>>>>>>> feature/login

解消とは、この3つの記号(<<<<<<<=======>>>>>>>)をすべて取り除き、どちらか一方、あるいは両方を踏まえた正しい一つの状態にファイルを書き直す作業です。ここで大切なのは、値の大小や新しさで機械的に選ばないこと。両方の変更が「なぜその値にしたのか」を確認し、意図を統合します。書き直したらgit addで解消済みとして載せ、マージならgit commit(またはそのまま確定)で確定させる流れです。判断がつかず作業を白紙に戻したいときはgit merge --abortで衝突前の状態へ安全に戻せます。

  1. git statusで衝突ファイルを特定する
  2. マーカーを手掛かりに双方の意図を確認する
  3. 3つのマーカーを消し、正しい一つの内容へ書き直す
  4. git addで解消済みとして載せる
  5. コミットして統合を確定する(迷えば--abortで戻す)

この一連の流れは、変更履歴の最小単位であるコミットの仕組みと粒度設計を押さえておくと、なぜ解消後に確定のコミットが要るのかまで含めて理解が通ります。

マージとリベースでコンフリクトの見え方と解消の判断はどう変わるか

同じ衝突でも、統合の方法がマージかリベースかで、解消の進み方が違います。マージは両ブランチの先端を一つのマージコミットで束ねるため、コンフリクトはその一度きり、まとめて表面化する形です。解消は一回で済み、履歴には分岐と統合の事実がそのまま残ります。障害調査で「いつ何を統合したか」を追いたい現場では、この履歴の素直さが利点です。

一方リベースは、自分のコミットを相手ブランチの先端へ一つずつ載せ直すため、コンフリクトはコミット単位で順番に発生します。同じ箇所を何度も直す手間はある一方、履歴は一本の直線に整い、後から読みやすくなるのが利点です。ここで判断が分かれます。共有済みのブランチをリベースで書き換えると、他のメンバーの手元の履歴と食い違い、かえって大きな衝突を招きます。そのため、リベースは自分だけのローカルな整理に限り、共有済みの統合はマージで行う、という切り分けが安全です。同じ箇所の解消を繰り返すのが煩わしい場合は、Gitに標準搭載された「解消の記録を再利用する仕組み」(rerere)を有効にすると、一度解いたパターンを次回から自動で当ててくれます。

観点 マージ リベース
衝突の出方 一度にまとめて コミット単位で順に
履歴の形 分岐と統合が残る 直線に整う
共有済みへの適用 安全 避ける

コンフリクトを減らす予防設計──ブランチ運用と統合頻度で衝突を先回りする

解消の速さを競うより、衝突が起きにくい開発フローを設計するほうが、チーム全体の手戻りを減らします。最も効くのは統合の頻度です。ブランチを長く育ててから一気にマージすると、その間に相手の変更が積み上がり、大量の衝突が一度に襲ってくる事態になりがちです。数日おき、できれば毎日メインブランチの更新を自分のブランチへ取り込み、差分を小さく保てば、衝突は起きても小粒で済みます。作業単位を小さく切って早くマージするほど、コンフリクトの総量は下がります。

次に効くのが担当範囲の分け方です。同じファイル、とりわけ設定ファイルや共通ユーティリティに複数人の変更が集中すると衝突が頻発します。機能ごとに責任範囲を分け、共通部分の変更はレビューで早めに調整する運用が予防になります。加えて見落とされがちなのが整形の衝突です。改行コードやインデント、コード整形ツールのバージョン差だけで全行が変更扱いになり、中身は同じなのに衝突する、という無駄が起こりがちです。整形ルールとツールをチームで固定し、CIで自動整形を通す設計にしておくと、この種の無意味な衝突を根から断てます。並行開発が前提のリポジトリでは、こうした運用ルールをどこに置くかを含め、リポジトリの構成とローカル・リモートの使い分けとあわせて設計すると効果が出ます。

  • メインの更新を毎日取り込み、ブランチの差分を小さく保つ
  • 作業単位を小さく切り、早くマージして衝突の総量を下げる
  • 担当範囲を分け、共通ファイルの同時編集を避ける
  • 整形ルールとツールを固定し、CIで自動整形して見せかけの衝突を消す

受託開発でコンフリクト対応をレビューとCIに結び付ける運用設計の方針

個人の慣れに任せると、コンフリクトの解消品質は担当者ごとにばらつきます。焦って片方を消し込む、マーカーの消し忘れをそのままコミットする、といった事故は、複数人・長期の受託開発ほど起きやすくなります。これをチームの仕組みで受け止めるには、三段構えが有効です。第一に、プルリクエスト単位でのレビューを前提に、解消の意図が説明できる粒度で統合すること。第二に、CIでビルドと自動テストを必ず通し、解消ミスによる壊れを機械的に検知すること。第三に、コンフリクトが多発する箇所を記録し、設計やファイル分割の見直しへつなげることです。

こうしたブランチ運用ルールの整備やレビュー・CI体制づくりは、内製化支援と保守運用の一環として外部の力を借りて進める選択肢もあります。一創では保守運用・内製化支援サービスで、Gitの運用ルール策定からレビュー・CIパイプラインの整備までを含め、衝突が起きにくい開発プロセスづくりを後押しする体制です。コンフリクト対応は単独の作業ではなく、変更を確認し合うコードレビューの観点と進め方と組み合わせることで、消し込み事故を防ぎながらチームの統合品質を底上げできます。

よくある質問

コンフリクトが起きたらデータは壊れますか?

壊れません。コンフリクトは、Gitが自動で統合できない箇所を保留して処理を止めている状態です。ファイルの中身は双方の変更が記号付きで並んで残っており、手作業で正しい一つの状態に書き直せば元に戻せます。判断に迷えばgit merge --abortで衝突前へ安全に戻せます。

コンフリクトマーカーの上と下はどちらを選べばよいですか?

大小や新しさで機械的に選ぶものではありません。上側が現在のブランチ、下側が取り込もうとしている変更で、それぞれ「なぜその内容にしたか」の意図があります。両方の意図を確認し、片方を採るか両方を踏まえた内容へ統合するかを判断し、3つのマーカーをすべて消して一つの状態に書き直します。

コンフリクトを未然に防ぐ方法はありますか?

統合の頻度を上げるのが最も効きます。ブランチを長く育てず、メインの更新を毎日取り込んで差分を小さく保てば、衝突は起きても小粒です。加えて担当範囲を分けて同じファイルの同時編集を避け、整形ルールとツールを固定してCIで自動整形すると、見せかけの衝突も減らせます。

マージとリベースはどちらで解消すべきですか?

共有済みのブランチはマージで統合するのが安全です。リベースは履歴を直線に整えられますが、共有済みの履歴を書き換えると他のメンバーと食い違います。リベースは自分だけのローカルな整理に限り、チームで共有した統合はマージで行う、という切り分けが実務では扱いやすくなります。

解消したのにまだコンフリクトと表示されるのはなぜですか?

マーカーを消してもgit addで解消済みとして載せていないと、衝突状態のままと見なされます。書き直したファイルをステージングし、マージなら確定のコミットを行って初めて解消が完了します。マーカーの消し忘れが残っていないかも、確定前に確認してください。

関連記事

資料請求

RELATED POSTS 関連記事