Gitマージの競合を解決する: CONFLICT (content): file.txtでマージの競合が発生しました

intermediate📦 Git2026-03-16| このエラーは、Linux、macOS、Windowsを含むGitが使用されるすべてのオペレーティングシステムで発生します。特定のOSバージョンやGitクライアントに固有のものではなく、Gitのバージョン管理プロセスの基本的な側面です。

Error Message

CONFLICT (content): Merge conflict in file.txt
#git#マージ#競合

要約:クイック修正

マージの競合が発生しましたか?最も迅速な解決方法は、競合している箇所をファイル内で手動で修正することです。以下に簡単なガイドを示します。

- **ステータスの確認:**
git status

このコマンドは、競合状態にあるファイルを表示します。「Unmerged paths」の下にリストされています。

- **開いて編集:** 各競合ファイルを好きなテキストエディタで開きます。Gitは以下のような特別なマーカーで競合を示します。
<<<<<<< HEAD
// 現在のブランチ (HEAD) からのコード
=======
// マージしようとしているブランチからのコード
>>>>>>> branch-name

どの変更を保持するか、または必要に応じて組み合わせるかを決定します。その後、決定的に重要なことですが、<<<<<<<=======、および>>>>>>>マーカーを削除します。

- **解決済みとしてマーク:** ファイルを編集し、すべての競合マーカーを削除したら、そのファイルの競合が解決されたことをGitに伝えます。
git add file.txt

競合しているすべてのファイルに対してこの手順を繰り返します。

- **マージの完了:** すべての競合が解決され、ステージングされたら、コミットでマージを完了します。
git commit -m "file.txtでのマージの競合を解決"

Gitは、マージコミットメッセージを自動で入力してくれることがよくあります。そのまま受け入れるか、変更しても構いません。

詳細な根本原因:なぜマージの競合が発生するのか

CONFLICT (content): Merge conflict in file.txt」エラーは、マージしようとしている2つの異なるブランチで、同じファイルの同じ行に行われた変更をGitが自動的に結合する方法を判別できない場合に発生します。

この現象が発生する理由を分解してみましょう。

- **履歴の分岐:** あなたとチームメイト(またはあなたが別の機能に取り組んでいる場合)が同じ時点(共通のコミット)から作業を開始したと想像してください。両者が異なる変更を行い、それらの変更を統合しようとすると、プロジェクトの履歴が分岐してしまいます。
- **同じ行での異なる変更:** 最も一般的な原因は、両方のブランチがファイル内の*全く同じ行*を修正した場合です。また、一方のブランチが、もう一方のブランチが修正した行を削除した場合にも発生します。このような場合、Gitはどちらの変更を採用すべきかを人間が決定する必要があります。Gitは通常、ファイル内の異なる部分への変更を自動的にマージするのに十分賢いですが、曖昧な場合は競合としてフラグを立てます。
- **三方向マージ:** Gitは「三方向マージ」戦略を使用します。これは、2つのブランチの共通の祖先を、両ブランチの最新バージョンと比較します。共通の祖先以降にファイルの同じセクションが両ブランチで異なる方法で変更された場合、競合が発生します。これはGitが決定を下せないため、あなたの入力を求めている状態です。

Gitが競合を検出すると、マージプロセスを一時停止します。問題のあるファイルを特別な状態にし、おなじみの<<<<<<<=======、および>>>>>>>マーカーで競合しているセクションを明確にマークします。これは、あなたが介入してこれらの曖昧さを手動で解決するための合図です。

競合の修正:選択肢

Gitマージの競合を解決するには、主に2つの方法があります。手動での編集、または専用のマージツールを使用することです。

アプローチ1:テキストエディタでの手動解決 (実践的な方法)

この方法は、特に小規模で直接的な競合の場合に、最も迅速で直接的な方法となることがよくあります。

- **競合ファイルの特定:**

マージを開始した後(例:git merge feature-branch)、競合メッセージが表示されたら、git statusを実行します。これは状況を把握するための頼りになるコマンドです。

git status

以下のような出力が表示されます。

On branch main
未マージのパスがあります。
  (競合を修正し、"git commit"を実行してください)
  (マージを中止するには "git merge --abort" を使用してください)

未マージのパス:
  (解決済みとしてマークするには "git add <ファイル>..." を使用してください)
            両方変更済み:   file.txt

このメッセージは、file.txtが現在競合していることを明確に示しています。

- **競合ファイルの編集:**

次に、file.txtをお好みのテキストエディタで開きます。内部には、次の例のような競合マーカーが表示されます。

// 変更されていない共有コード
<<<<<<< HEAD
// これは現在のブランチ (HEAD) からのコンテンツです。
// おそらく、ここで新しい関数を追加したり、バグを修正したりしたのでしょう。
=======
// これはマージしようとしているブランチ(例:「feature-branch」)からのコンテンツです。
// 同僚がここで異なるロジックを実装した可能性があります。
>>>>>>> feature-branch
// 変更されていないその他の共有コード
    `<<<<<<< HEAD`: これは、現在アクティブなブランチからの変更の始まりを示します。
    - `=======`: この行は区切り線として機能し、あなたの変更と入ってくる変更を分離します。
    - `>>>>>>> branch-name`: これは、マージしようとしているブランチからの変更の終わりを示します。

あなたの仕事は、これらのセクションを慎重に確認することです。次のことを決定する必要があります。

    - どちらのバージョンを保持すべきか?
    - 両方のバージョンの一部を組み合わせるべきか?
    - 両方の変更セットを統合する、全く新しいより良い方法は存在するか?

**解決例:**を考えてみましょう。 仮にfile.txtが最初、以下を含んでいたとします。

function greet() {
    return "Hello";
}

そして、あなたのHEADブランチがそれを以下のように変更しました。

function greet() {
    return "Hello, World!";
}

一方、マージしようとしているfeature-branchはそれを以下のように変更しました。

function greet() {
    return "Hi!";
}

競合したファイルは、次のように表示されます。

function greet() {
<<<<<<< HEAD
    return "Hello, World!";
=======
    return "Hi!";
>>>>>>> feature-branch
}

「Hello, World!」を保持するか、新しい結合されたメッセージを作成することで、これを解決できます。例えば、「Hello, World!」を保持する場合:

function greet() {
    return "Hello, World!";
}

あるいは、ロジックが結合されたアプローチを許容する場合:

function greet() {
    // ここでは、どの挨拶が適切かを決定するか、特定のアプリケーションロジックのために結合します
    return "Greetings, fellow developer!";
}

**絶対に重要:<<<<<<<=======、および>>>>>>>のすべての行を削除する必要があります。**これらのマーカーがなくなると、Gitはコミットを許可しません。

- **解決済みファイルをステージング:**

手動でfile.txtを編集し、すべての競合マーカーを削除したら、変更を保存します。その後、そのファイルの競合が解決されたことをGitに伝えるために、ステージングエリアに追加します。

git add file.txt

再度git statusを実行します。今度はfile.txtが「Unmerged paths」ではなく「Changes to be committed」の下にリストされているはずです。これは、次のステップの準備ができたことを確認するものです。

- **マージをコミット:**

競合するすべてのファイルが解決され、ステージングされたら、マージコミットを作成してマージプロセスを完了します。

git commit

このコマンドは、デフォルトのテキストエディタを起動し、マージコミットメッセージが事前に入力された状態で表示します。このメッセージは通常、どのブランチがマージされたか、および競合が解決されたことを説明しています。必要に応じてこのメッセージをカスタマイズし、エディタを保存して閉じると、コミットが確定されます。

アプローチ2:ビジュアルマージツールの使用 (グラフィカルヘルパー)

競合が複雑になった場合や、単純にグラフィカルインターフェースを好む場合、Gitは外部マージツールに対する堅牢なサポートを提供します。

- **マージツールの設定 (まだ設定していない場合):**

Gitを設定して、Beyond Compare、KDiff3、Meldなどの人気ツールや、IDEの組み込みマージ機能(VS Codeなど)を使用できます。例えば、VS Codeを優先マージツールとして統合するには、以下のようにします。

git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait --merge $REMOTE $LOCAL $BASE $MERGED'
git config --global mergetool.vscode.trustExitCode false

注: 正確なコマンドは、選択したツールやオペレーティングシステムによって若干異なる場合があります。正確な設定手順については、必ず使用するツールのドキュメントを参照してください。

- **マージツールの起動:**

ツールが設定され、Gitが競合を検出したら、単に以下を実行します。

git mergetool

Gitは競合する各ファイルを順に処理し、設定されたマージツールを1つずつ起動します。通常、ツールは共通の祖先、あなたの変更、そして取り込む変更という3つまたは4つのパネルを表示します。一部のツールは最終的なマージ結果も表示します。この視覚的な比較により、保持したい部分や組み合わせたい部分を選択するのが非常に容易になります。

- **ツールを保存して終了:**

マージツール内で視覚的に競合を解決した後、変更を保存してツールを閉じます。Gitは自動的にファイルをステージングし、その過程で解決済みとしてマークします。

- **マージをコミット:**

手動解決と同様に、すべての競合が解決されたら(手動またはツール経由で)、git commitを実行してマージを完了します。

アプローチ3:マージの中止 (状況が悪化した時)

時として、競合が圧倒的に感じられたり、マージを時期尚早に開始したことに気づいたりすることがあります。そのような場合、マージ操作を安全に中止し、マージを開始するのリポジトリの状態に戻すことができます。

- **マージを中止:**
git merge --abort

この強力なコマンドは、マージプロセスを完全に停止させます。作業ディレクトリとGitインデックスを、git mergeを呼び出す前の状態に正確にリセットします。重要: 作業ディレクトリ内のコミットされていない変更は、Gitが元に戻す状態と競合する場合、失われる可能性があることに注意してください。マージを試みる前に、作業をコミットまたはスタッシュしておくことは常に良い習慣です。

検証手順:マージの確認

マージの競合をうまく解決し、重要なマージコミットを作成した後、すべてが正常であることを確認するために少し時間をかけるのは賢明な習慣です。これにより、あなたの努力が新たな問題を引き起こしていないことを保証できます。

- **Gitステータスの確認:**

最初に行うべきことは、常にリポジトリのステータスを確認することです。

git status

On branch main nothing to commit, working tree clean」のような安心できる出力は、マージが成功し、未解決の変更や競合が残っていないことを意味します。

- **コミット履歴の確認:**

次に、コミット履歴を確認します。これにより、マージコミットが正しく作成され、履歴が変更の統合方法を正確に反映していることを確認できます。

git log --oneline --graph --all

このコマンドは、コミット履歴を簡潔なグラフィカルビューで提供します。マージコミットをすばやく視覚化し、ブランチがどのように結合されたかを確認するのに最適です。

- **アプリケーション/コードベースのテスト:**

最終的なテストは、コードを実行することです!自動テストを実行したり、ビルドプロセスを開始したり、マージされた変更の影響を受けた機能を手動でテストしたりしてください。この重要な手順は、競合の解決が誤って新しいバグを導入したり、既存の機能を破壊したりしていないことを確認します。この手順を飛ばさないでください!

さらに読む & リソース

- [Gitのブランチ - 基本的なブランチ操作とマージ](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging)
- [Gitツール - 高度なマージ](https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging)
- 具体的な使用方法や高度な機能については、選択したマージツールのドキュメントを参照してください。

Related Error Notes