Gitでよく起こる「コンフリクト」、原因と対処法の解説

アイキャッチ画像

Gitを使ってチームで開発していると、「コンフリクト」という言葉を目にすることがあります。

Git初心者の方の中には、

  • 「コンフリクトって何が起きているの?」
  • 「エラーが出たけど、どうすればいい?」
  • 「自分の変更が消えてしまうのでは?」
  • 「そもそも、なぜコンフリクトが起こるの?」

と疑問に思う方もいるのではないでしょうか。

コンフリクトは、Gitを使ったチーム開発では珍しいものではありません。原因と基本的な対処方法を理解しておけば、落ち着いて対応できます。

今回は、Git初心者の方に向けて、コンフリクトが発生する原因から具体的な解決方法、コンフリクトを防ぐためのポイントまで、SEの視点からわかりやすく解説します。

そもそもGitの「コンフリクト」とは?

コンフリクト(Conflict)とは、複数の変更をGitが自動的に統合できない状態のことです。

例えば、同じファイルの同じ部分をAさんとBさんがそれぞれ編集したとします。

Aさんは、

ユーザー情報を表示します。

を、

ユーザー情報を一覧表示します。

に変更しました。

一方、Bさんは同じ行を、

ユーザー情報を詳細表示します。

に変更したとします。

この2つの変更をGitが統合しようとしても、「一覧表示」と「詳細表示」のどちらを採用すればよいのか、Git自身では判断できません。

このように、Gitがどちらの変更を残すべきか判断できない場合にコンフリクトが発生します。

重要なのは、コンフリクトが必ずしも「Gitの故障」や「重大なエラー」というわけではないということです。

むしろ、チームで同じファイルを編集していると起こり得る、Gitでは一般的な現象です。

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

コンフリクトの主な原因は、複数人が同じファイルの同じ箇所、または近い箇所を変更することです。

例えば、次のような状況を考えてみましょう。

main

  │

  ├── Aさん:画面のタイトルを変更

  │

  └── Bさん:同じ画面のタイトルを変更

AさんとBさんがそれぞれ別のブランチで作業している場合、Gitはそれぞれの変更を別々に管理できます。

しかし、最終的に両方の変更を1つにまとめようとすると、同じ箇所に異なる変更が存在するため、Gitだけでは判断できない場合があります。

コンフリクトが起こりやすいケース

代表的なケースには、次のようなものがあります。

  • 複数人が同じファイルを編集している
  • 複数人が同じ行を変更している
  • 一方がファイルを変更している間に、別の人が同じ箇所を変更した
  • 長期間ブランチを更新せずに作業している

特に、1つのファイルを多くのメンバーが頻繁に変更するプロジェクトでは、コンフリクトが発生する可能性も高くなります。

コンフリクトが発生するとどうなる?

コンフリクトが発生すると、Gitは自動的なマージを中断します。

例えば、次のような表示になることがあります。

<<<<<<< HEAD

ユーザー情報を一覧表示します。

=======

ユーザー情報を詳細表示します。

>>>>>>> feature/user-detail

この記号は、Gitが「この部分については自動で判断できません」と示しているものです。

それぞれの記号には意味があります。

<<<<<<< HEAD

現在チェックアウトしているブランチ側の変更

=======

マージしようとしているブランチ側の変更

>>>>>>> feature/user-detail

この状態では、開発者が内容を確認し、最終的にどの内容を残すのかを判断する必要があります。

コンフリクトが発生したときの基本的な対処方法

ここからは、実際にコンフリクトが発生した場合の基本的な流れを見てみましょう。

1. まずコンフリクトが発生したファイルを確認する

git statusを実行すると、コンフリクトが発生しているファイルを確認できます。

git status

例えば、次のような表示があったとします。

both modified:   src/user.js

これは、src/user.jsが複数の変更によって編集されており、Gitが自動的に統合できなかったことを示しています。

2. ファイルを開いてコンフリクト箇所を確認する

対象ファイルを開くと、次のような記号が入っている場合があります。

<<<<<<< HEAD

ユーザー情報を一覧表示します。

=======

ユーザー情報を詳細表示します。

>>>>>>> feature/user-detail

ここで、どちらの変更を採用するのかを確認します。

例えば「一覧表示」を採用するのであれば、最終的に次のようにします。

ユーザー情報を一覧表示します。

ポイントは、<<<<<<<、=======、>>>>>>>などのコンフリクト用の記号を残さないことです。

3. 修正したファイルをGitに登録する

コンフリクトを解消したら、修正したファイルをgit addします。

git add src/user.js

これはGitに対して、

「このファイルのコンフリクトを解消しました」

と伝える操作でもあります。

4. 状態を確認する

再度、

git status

を実行して、コンフリクトが解消されていることを確認します。

5. マージの場合はコミットする

マージによるコンフリクトを解消した場合は、必要に応じてコミットします。

git commit

これでマージ処理を完了できます。

なお、実際の操作はプロジェクトのGit運用ルールによって異なる場合があります。特に、Pull Requestを利用している場合は、チームのルールを確認してから作業することが大切です。

コンフリクトを防ぐためにできること

コンフリクトを完全になくすことは難しいですが、発生する可能性を減らすことはできます。

こまめに最新の変更を取り込む

長期間、自分のブランチを更新しないまま作業すると、その間に他のメンバーの変更が蓄積します。

そのため、プロジェクトのルールに従い、適切なタイミングで最新の変更を取り込みましょう。

1つの作業を長期間抱え込まない

大きな機能を1つのブランチで長期間開発していると、mainブランチとの差分が大きくなり、コンフリクトのリスクも高くなります。

可能な範囲で作業を小さく分割し、適切な単位で変更を共有することが重要です。

作業範囲をチームで共有する

「誰がどのファイルを変更しているのか」が分かっていれば、同じ箇所を同時に編集する可能性を減らせます。

チーム開発では、Gitの操作だけでなく、コミュニケーションもコンフリクト対策になります。

初心者がやりがちな注意点

Git初心者の場合、コンフリクトが発生すると焦ってしまうかもしれません。

しかし、何が起きているのか分からない状態でコマンドを実行し続けるのは避けましょう。

特に、

  • コンフリクトの内容を確認せずにファイルを上書きする
  • 相手の変更を確認せずに削除する
  • よく分からないままgit resetなどを実行する
  • コンフリクトマーカーを残したままコミットする

といった対応には注意が必要です。

分からない場合は、まずgit statusで現在の状態を確認し、プロジェクトのルールや先輩・担当者に確認しましょう。