Git のコンフリクトを解消する方法|初心者でも安心の完全ガイド

「コンフリクトが発生しました…」

チーム開発でGitを使っていると、必ずこのメッセージに遭遇します。初めて見たときは「何かやらかした!?」と焦ってしまいますよね。

でも安心してください。コンフリクトはエラーではなく、Gitがあなたの判断を求めているだけです。

この記事では、コンフリクトが発生する仕組みから、具体的な解消手順まで、初心者の方にも分かりやすく解説していきます。

スポンサーリンク
  1. コンフリクト(競合)とは何か?
    1. コンフリクトが発生する典型的な状況
    2. コンフリクトは悪いことではない
  2. コンフリクトの検出:どうやって気づくか
    1. マージ時のコンフリクト
    2. プル時のコンフリクト
    3. リベース時のコンフリクト
    4. 状況を確認するコマンド
  3. コンフリクトマーカーの読み方
    1. コンフリクトマーカーの意味
    2. マーカーの見方の例
  4. 方法1:コマンドラインでコンフリクトを解消する
    1. ステップ1:コンフリクトファイルを特定
    2. ステップ2:ファイルを編集
    3. ステップ3:変更内容を決定
    4. ステップ4:解決したファイルをステージング
    5. ステップ5:すべてのコンフリクトを確認
    6. ステップ6:マージをコミット
  5. 方法2:VS Codeを使ってGUIで解消する
    1. VS Codeでのコンフリクト表示
    2. 操作手順
    3. マージエディター機能
  6. 方法3:GitHubのWeb UIで解消する
    1. 解消可能な条件
    2. 操作手順
    3. GitHubでの編集例
  7. マージを中止する方法
    1. マージの中止
    2. リベースの中止
    3. 中止時の注意点
  8. コンフリクト解消のトラブルシューティング
    1. コンフリクトマーカーが残っていないか確認
    2. 誤って追加した場合のリセット
    3. マージコミット後に問題に気づいた
    4. 複雑すぎて分からない場合
  9. コンフリクトを防ぐためのベストプラクティス
    1. 1. こまめにマージ・リベースする
    2. 2. 作業前に最新の状態を取得
    3. 3. ファイルやコードの役割を明確に分ける
    4. 4. 小さく頻繁にコミット
    5. 5. チーム内でコミュニケーションを取る
    6. 6. Pull Requestのレビューを迅速に
    7. 7. リベースとマージを使い分ける
  10. まとめ:コンフリクトは怖くない

コンフリクト(競合)とは何か?

コンフリクト(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.jsstyles/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:変更内容を比較表示

操作手順

  1. コンフリクトファイルを開く
  2. 各コンフリクト箇所で適切なボタンをクリック
  3. すべてのコンフリクトを解決
  4. ファイルを保存
  5. ターミナルで git addgit commit を実行

マージエディター機能

VS Codeの「Resolve in Merge Editor」ボタンをクリックすると、より高度なマージエディターが開きます。

画面構成

  • 左側:現在のブランチの内容(閲覧のみ)
  • 右側:マージ元ブランチの内容(閲覧のみ)
  • 下側:最終的な統合結果(編集可能)

操作方法

  1. 左右の画面で「Accept」ボタンをクリックすると下側に反映
  2. 下側の画面で直接編集も可能
  3. 「Complete Merge」をクリックして完了

この方法なら、コマンド操作が苦手な方でも直感的にコンフリクトを解消できます。

方法3:GitHubのWeb UIで解消する

シンプルなコンフリクトであれば、GitHub上で直接解消することもできます。

解消可能な条件

GitHubのWeb UIで解消できるのは:

  • テキストファイルのコンフリクト
  • 同じ行の異なる変更によるコンフリクト
  • ファイルサイズが200KB以内
  • バイナリファイルではない

複雑なコンフリクトは、ローカルで解消する必要があります。

操作手順

  1. Pull Requestページを開く
  2. 「This branch has conflicts that must be resolved」の表示を確認
  3. 「Resolve conflicts」ボタンをクリック
  4. エディタでコンフリクトマーカーを編集
  5. すべて解決したら「Mark as resolved」をクリック
  6. 「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(マージ前のブランチ)に戻す」という意味です。

複雑すぎて分からない場合

どうしても解決できない場合は:

  1. マージを中止する(git merge --abort
  2. チームメンバーに相談する
  3. 変更内容を小分けにして、もう一度マージを試みる

コンフリクトを防ぐためのベストプラクティス

コンフリクトは避けられませんが、発生頻度を減らすことはできます。

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のコンフリクト解消方法をまとめます。

コンフリクト発生時の基本フロー

  1. git status で状況を確認
  2. コンフリクトファイルを開く
  3. コンフリクトマーカーを見て変更内容を決定
  4. マーカーを削除して編集
  5. git add でステージング
  6. すべて解決したら git commit

状況別の解消方法

状況おすすめ方法難易度
シンプルなコンフリクトGitHub Web UI★☆☆
ローカルでの作業VS Code★☆☆
複雑なコンフリクトコマンドライン + エディタ★★☆
解決できないマージ中止★☆☆

覚えておきたい重要ポイント

  • コンフリクトはエラーではなく、Gitがあなたの判断を求めている状態
  • コンフリクトマーカー(<<<<<<<=======>>>>>>>)は必ず削除
  • git add でコンフリクト解決済みとマークする
  • マージを中止したいときは git merge --abort
  • こまめなマージとチームでのコミュニケーションでコンフリクトを予防

最後に:焦らず、一つずつ

コンフリクトに遭遇しても、焦る必要はありません。

落ち着いて:

  1. 何が起きているか確認
  2. どの変更を残すべきか考える
  3. 一つずつファイルを解消していく

この手順を踏めば、確実にコンフリクトを解消できます。

何度か経験すれば、コンフリクト解消はルーティン作業になります。最初は時間がかかっても、徐々に慣れていきますので、あきらめずに取り組んでみてください。

あなたのチーム開発が、よりスムーズに進むことを願っています!

コメント

タイトルとURLをコピーしました