「コンフリクトが発生しました…」
チーム開発でGitを使っていると、必ずこのメッセージに遭遇します。初めて見たときは「何かやらかした!?」と焦ってしまいますよね。
でも安心してください。コンフリクトはエラーではなく、Gitがあなたの判断を求めているだけです。
この記事では、コンフリクトが発生する仕組みから、具体的な解消手順まで、初心者の方にも分かりやすく解説していきます。
コンフリクト(競合)とは何か?

コンフリクト(conflict)とは、日本語で「競合」や「衝突」を意味します。
Gitでは、異なるブランチで同じファイルの同じ箇所を別々に変更したとき、Gitが「どちらの変更を採用すべきか」を自動的に判断できない状態を指します。
コンフリクトが発生する典型的な状況
ケース1:同じ行を異なる内容に変更
# mainブランチ
const message = "こんにちは";
# featureブランチ
const message = "Hello";
両方のブランチで同じ行を編集しているため、Gitは「こんにちは」と「Hello」のどちらを採用すべきか判断できません。
ケース2:ファイルの削除と編集が重なる
- Aさんがmainブランチでファイルを削除
- Bさんがfeatureブランチで同じファイルを編集
Gitは「存在しないファイルをどう扱うべきか」が分からず、コンフリクトになります。
ケース3:複数人が同時に作業
チーム開発では、知らないうちに他のメンバーと同じファイルを編集していることがよくあります。これが最も一般的なコンフリクトの原因です。
コンフリクトは悪いことではない
重要なのは、コンフリクトは正常な動作だということです。
Gitはあなたとチームメンバーのコードを勝手に上書きせず、必ず確認を求めてくれています。これはむしろ「Gitがチームの成果を守ってくれている」証拠なのです。
コンフリクトの検出:どうやって気づくか
コンフリクトは、主に以下の操作中に発生します。
マージ時のコンフリクト
ブランチをマージしようとしたとき:
git merge feature-branch
コンフリクトが発生すると、こんなメッセージが表示されます。
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
プル時のコンフリクト
リモートから変更を取り込むとき:
git pull origin main
こちらも同様にコンフリクトが通知されます。
リベース時のコンフリクト
ブランチをリベースするとき:
git rebase main
リベースでもコンフリクトは発生します。
状況を確認するコマンド
コンフリクトが発生したら、まず状況を確認しましょう。
git status
出力例:
On branch feature-login
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: src/App.js
both modified: styles/main.css
no changes added to commit
この出力から、src/App.js と styles/main.css の2つのファイルでコンフリクトが発生していることが分かります。
コンフリクトマーカーの読み方
コンフリクトが発生したファイルを開くと、次のような記号(コンフリクトマーカー)が挿入されています。
<!DOCTYPE html>
<html>
<head>
<title>Sample Page</title>
</head>
<body>
<<<<<<< HEAD
<h1>こんにちは、世界!</h1>
=======
<h1>Hello, World!</h1>
>>>>>>> feature-english
</body>
</html>
コンフリクトマーカーの意味
<<<<<<< HEAD
- 現在のブランチ(マージ先)の内容の開始位置
- HEADは現在チェックアウトしているブランチの最新コミットを指す
=======
- 2つの変更内容を区切る境界線
- この記号より上が現在のブランチ、下がマージしようとしているブランチ
>>>>>>> feature-english
- マージ元のブランチの内容の終了位置
- ブランチ名やコミットIDが表示される
マーカーの見方の例
function greet() {
<<<<<<< HEAD
console.log("ようこそ!");
return "日本語の挨拶";
=======
console.log("Welcome!");
return "English greeting";
>>>>>>> feature-translation
}
この例では:
- 上側(HEAD):日本語メッセージを表示
- 下側(feature-translation):英語メッセージを表示
どちらを採用するか、あるいは両方を統合するかを決める必要があります。
方法1:コマンドラインでコンフリクトを解消する
最も基本的な解消方法は、テキストエディタで直接ファイルを編集することです。
ステップ1:コンフリクトファイルを特定
git status
Unmerged paths: の下に表示されるファイルがコンフリクト対象です。
ステップ2:ファイルを編集
お好みのエディタでファイルを開きます。
# VS Codeで開く場合
code src/App.js
# Vimで開く場合
vim src/App.js
ステップ3:変更内容を決定
コンフリクトマーカーを見て、以下のいずれかを選択します。
パターンA:現在のブランチの変更を採用
// 元のコンフリクト
<<<<<<< HEAD
const color = "blue";
=======
const color = "red";
>>>>>>> feature-theme
// 解決後(blueを採用)
const color = "blue";
パターンB:マージ元ブランチの変更を採用
// 解決後(redを採用)
const color = "red";
パターンC:両方の変更を統合
// 解決後(両方の要素を組み合わせる)
const colors = {
primary: "blue",
accent: "red"
};
重要:コンフリクトマーカーを必ず削除
<<<<<<<、=======、>>>>>>> の記号は必ず削除してください。これらが残っていると、プログラムが正しく動作しません。
ステップ4:解決したファイルをステージング
編集が完了したら、ファイルをステージングします。
git add src/App.js
git add することで「このファイルのコンフリクトは解決済み」とGitに伝えます。
ステップ5:すべてのコンフリクトを確認
複数のファイルでコンフリクトがある場合、すべて解決する必要があります。
git status
Unmerged paths: が表示されなくなれば、すべて解決完了です。
ステップ6:マージをコミット
git commit
コミットメッセージのエディタが開きます。デフォルトで「Merge branch ‘feature-branch’」のようなメッセージが用意されているので、必要に応じて編集して保存します。
または、直接メッセージを指定することもできます。
git commit -m "Merge feature-branch: コンフリクトを解消"
これでコンフリクトの解消とマージが完了しました!
方法2:VS Codeを使ってGUIで解消する

VS Codeには、コンフリクト解消を支援する便利な機能が組み込まれています。
VS Codeでのコンフリクト表示
コンフリクトが発生したファイルを開くと、次のように表示されます。
<<<<<<< HEAD (Current Change)
const greeting = "こんにちは";
=======
const greeting = "Hello";
>>>>>>> feature-english (Incoming Change)
各コンフリクト箇所の上に、次のようなボタンが表示されます。
- Accept Current Change:現在のブランチの変更を採用
- Accept Incoming Change:マージ元ブランチの変更を採用
- Accept Both Changes:両方の変更を保持
- Compare Changes:変更内容を比較表示
操作手順
- コンフリクトファイルを開く
- 各コンフリクト箇所で適切なボタンをクリック
- すべてのコンフリクトを解決
- ファイルを保存
- ターミナルで
git addとgit commitを実行
マージエディター機能
VS Codeの「Resolve in Merge Editor」ボタンをクリックすると、より高度なマージエディターが開きます。
画面構成
- 左側:現在のブランチの内容(閲覧のみ)
- 右側:マージ元ブランチの内容(閲覧のみ)
- 下側:最終的な統合結果(編集可能)
操作方法
- 左右の画面で「Accept」ボタンをクリックすると下側に反映
- 下側の画面で直接編集も可能
- 「Complete Merge」をクリックして完了
この方法なら、コマンド操作が苦手な方でも直感的にコンフリクトを解消できます。
方法3:GitHubのWeb UIで解消する
シンプルなコンフリクトであれば、GitHub上で直接解消することもできます。
解消可能な条件
GitHubのWeb UIで解消できるのは:
- テキストファイルのコンフリクト
- 同じ行の異なる変更によるコンフリクト
- ファイルサイズが200KB以内
- バイナリファイルではない
複雑なコンフリクトは、ローカルで解消する必要があります。
操作手順
- Pull Requestページを開く
- 「This branch has conflicts that must be resolved」の表示を確認
- 「Resolve conflicts」ボタンをクリック
- エディタでコンフリクトマーカーを編集
- すべて解決したら「Mark as resolved」をクリック
- 「Commit merge」をクリック
GitHubでの編集例
Web上のエディタで、コンフリクトマーカーを直接編集します。
<!-- 編集前 -->
<<<<<<< main
<h1>メインページ</h1>
=======
<h1>トップページ</h1>
>>>>>>> feature-title
<!-- 編集後 -->
<h1>トップページ</h1>
マーカーを削除して、採用したい内容だけを残します。
複数のファイルにコンフリクトがある場合は、左側のファイル一覧から次のファイルを選択して、同じ作業を繰り返します。
マージを中止する方法
「コンフリクトが複雑すぎて今は解決できない」「間違ったブランチをマージしてしまった」という場合、マージ自体を中止できます。
マージの中止
git merge --abort
このコマンドで、マージを開始する前の状態に戻ります。
使える条件
- マージ中(コンフリクト発生中)の状態のみ
- コミットまで完了した後は使えない
技術的には、.git/MERGE_HEAD というファイルが存在する間だけ有効です。
リベースの中止
リベース中のコンフリクトなら:
git rebase --abort
中止時の注意点
マージを中止すると:
- 作業ディレクトリとインデックスがマージ前の状態に戻る
- コンフリクト解消のために編集した内容は失われる
- コミット前の未保存の変更が消える可能性がある
そのため、重要な変更は事前に git stash で保存しておくと安全です。
コンフリクト解消のトラブルシューティング
コンフリクトマーカーが残っていないか確認
コンフリクトマーカーを削除し忘れていないかチェックできます。
git diff --check
マーカーが残っている場合、警告が表示されます。
誤って追加した場合のリセット
間違えて git add してしまった場合:
git reset HEAD ファイル名
これでステージングを取り消せます。
マージコミット後に問題に気づいた
マージコミット後に「やっぱり間違えた」と気づいた場合:
# 直前のコミットを取り消す
git reset --hard HEAD~1
または、マージだけを取り消す:
git revert -m 1 HEAD
-m 1 は「親コミット1(マージ前のブランチ)に戻す」という意味です。
複雑すぎて分からない場合
どうしても解決できない場合は:
- マージを中止する(
git merge --abort) - チームメンバーに相談する
- 変更内容を小分けにして、もう一度マージを試みる
コンフリクトを防ぐためのベストプラクティス
コンフリクトは避けられませんが、発生頻度を減らすことはできます。
1. こまめにマージ・リベースする
長期間ブランチを分離したままにすると、コンフリクトが複雑化します。
# 定期的にmainブランチの変更を取り込む
git checkout feature-branch
git pull origin main
週に1〜2回、メインブランチの変更を自分のブランチに取り込む習慣をつけましょう。
2. 作業前に最新の状態を取得
作業を始める前に、必ずリモートから最新の変更を取得します。
git pull origin main
これで他のメンバーの最新の変更が取り込まれます。
3. ファイルやコードの役割を明確に分ける
チームで作業を分担する際:
- 機能ごとにファイルを分ける
- 同じファイルを同時に編集しない
- 共通部分の編集はチームで調整する
4. 小さく頻繁にコミット
大きな変更を1つのコミットにまとめるより、小さく分けてコミットする方が:
- コンフリクトが発生しても影響範囲が小さい
- 何が変更されたか分かりやすい
- 問題があれば部分的に戻せる
5. チーム内でコミュニケーションを取る
「今この機能を実装している」「このファイルを編集する予定」といった情報を共有しましょう。
Slackやチャットで:
「今から settings.js を編集します」
「ログイン機能のリファクタリング中です」
こういった簡単な連絡で、コンフリクトの多くを防げます。
6. Pull Requestのレビューを迅速に
Pull Requestが長期間放置されると、その間にmainブランチが進んでコンフリクトが発生します。
レビューと承認を素早く行うことで、コンフリクトの発生を抑えられます。
7. リベースとマージを使い分ける
マージ
- 履歴が複雑になるが、安全
- チームで共有しているブランチに適している
リベース
- 履歴が一直線になり見やすい
- 自分専用のブランチに適している
- 共有ブランチでは使わない
状況に応じて使い分けることで、無用なコンフリクトを避けられます。
まとめ:コンフリクトは怖くない
Gitのコンフリクト解消方法をまとめます。
コンフリクト発生時の基本フロー
git statusで状況を確認- コンフリクトファイルを開く
- コンフリクトマーカーを見て変更内容を決定
- マーカーを削除して編集
git addでステージング- すべて解決したら
git commit
状況別の解消方法
| 状況 | おすすめ方法 | 難易度 |
|---|---|---|
| シンプルなコンフリクト | GitHub Web UI | ★☆☆ |
| ローカルでの作業 | VS Code | ★☆☆ |
| 複雑なコンフリクト | コマンドライン + エディタ | ★★☆ |
| 解決できない | マージ中止 | ★☆☆ |
覚えておきたい重要ポイント
- コンフリクトはエラーではなく、Gitがあなたの判断を求めている状態
- コンフリクトマーカー(
<<<<<<<、=======、>>>>>>>)は必ず削除 git addでコンフリクト解決済みとマークする- マージを中止したいときは
git merge --abort - こまめなマージとチームでのコミュニケーションでコンフリクトを予防
最後に:焦らず、一つずつ
コンフリクトに遭遇しても、焦る必要はありません。
落ち着いて:
- 何が起きているか確認
- どの変更を残すべきか考える
- 一つずつファイルを解消していく
この手順を踏めば、確実にコンフリクトを解消できます。
何度か経験すれば、コンフリクト解消はルーティン作業になります。最初は時間がかかっても、徐々に慣れていきますので、あきらめずに取り組んでみてください。
あなたのチーム開発が、よりスムーズに進むことを願っています!

コメント