Git コース
1 2 3 4
コンフリクトを解消しよう | Git レッスン6
⏱ 約25分 やってみよう 1 クイズ 1
🎯 このレッスンで学ぶこと
- コンフリクトが発生する条件を説明できます。
- コンフリクトマーカー(<<<, ===, >>>)を読めます。
- コンフリクトを手動で解消してコミットできます。
- コンフリクトを予防するコツを知っています。
📖 復習 — ブランチとマージのおさらい
- ブランチ名は
feature/fix/などのプレフィックスをつける git switch -c ブランチ名で作成+切り替えgit merge ブランチ名で変更を統合- マージ後はブランチを削除する
💥 1. コンフリクトとは?
コンフリクト(競合)とは、2つのブランチで同じファイルの同じ行を別々に変更したとき、Git がどちらを採用すべきかわからなくなる状態です。
📓 たとえ話: 2人が同じノートの同じ行に別のことを書いた。ノートを1冊にまとめるとき、どっちを残す? → 2人で話し合って決める必要がある。これがコンフリクト解消です。
自動マージできるケース vs できないケース:
- ✅ 自動マージ: 別のファイルを変更 / 同じファイルでも別の行を変更
- ❌ コンフリクト: 同じファイルの同じ行を両方で変更
💡 怖がらなくて大丈夫!
コンフリクトが起きても、
コンフリクトが起きても、
git merge --abort でいつでもマージ前の状態に戻れます。落ち着いて対処しましょう。
🔍 2. コンフリクトを体験してみよう
意図的にコンフリクトを起こして、解消の練習をしましょう。
- main で変更してコミット:
git switch main echo "こんにちは" > greeting.txt git add greeting.txt git commit -m "挨拶ファイルを追加" - feature ブランチで同じ行を別の内容に変更:
git switch -c feature/change-greeting echo "Hello" > greeting.txt git add greeting.txt git commit -m "挨拶を英語に変更" - main に戻ってマージ → コンフリクト発生!
git switch main git merge feature/change-greeting以下のようなメッセージが表示されます:
CONFLICT (content): Merge conflict in greeting.txt Automatic merge failed; fix conflicts and then commit the result.
💡 ブランチを作ると、その時点の main の内容がコピーされます。
つまり feature ブランチを作った時点では greeting.txt の中身は「こんにちは」です。ここから別の内容に変えることでコンフリクトが起きます。
つまり feature ブランチを作った時点では greeting.txt の中身は「こんにちは」です。ここから別の内容に変えることでコンフリクトが起きます。
📖 3. コンフリクトマーカーの読み方
コンフリクトが起きたファイルを開くと、以下のようなマーカーが挿入されています:
<<<<<<< HEAD
こんにちは
=======
Hello
>>>>>>> feature/change-greeting <<<<<<< HEAD— ここから「今いるブランチ(main)」の内容=======— 区切り線(ここで2つの変更が分かれる)>>>>>>> feature/change-greeting— ここまでが「マージ元ブランチ」の内容
💡 VS Code ならもっと簡単!
VS Code ではコンフリクト箇所がハイライトされ、「Accept Current Change」「Accept Incoming Change」「Accept Both Changes」のボタンで選択できます。
VS Code ではコンフリクト箇所がハイライトされ、「Accept Current Change」「Accept Incoming Change」「Accept Both Changes」のボタンで選択できます。
解消の before / after:
Before(マーカーあり):
<<<<<<< HEAD
こんにちは
=======
Hello
>>>>>>> feature/change-greeting After(両方を組み合わせた例):
こんにちは / Hello マーカーを全て消して、最終的に残したい内容だけにします。
🔧 4. コンフリクトの解消手順
4ステップで解消します:
- ファイルを開いてマーカーを確認する
git statusでどのファイルにコンフリクトがあるか確認できます:$ git status On branch main You have unmerged paths. Unmerged paths: (use "git add <file>..." to mark resolution) both modified: greeting.txt - どちらの内容を残すか決める(または両方を組み合わせる)
# 例: 両方を組み合わせる場合 こんにちは / Hello - マーカー(<<<, ===, >>>)を全て削除する
- git add → git commit で解消を記録する
git add greeting.txt git commit(コミットメッセージは自動で「Merge branch ...」が入ります)
⚠️ マーカーを消し忘れてコミットしないで!
<<<<<<< や ======= がファイルに残ったままコミットすると、コードが壊れます。必ず全てのマーカーを削除してからコミットしましょう。
⚠️ コンフリクト中に別の作業をしない!
コンフリクトが発生したら、まず解消を完了させてからほかの作業に移りましょう。中途半端な状態で別の作業をすると混乱します。
コンフリクトが発生したら、まず解消を完了させてからほかの作業に移りましょう。中途半端な状態で別の作業をすると混乱します。
🛡️ 5. コンフリクトを予防するコツ
- こまめに git pull して最新を取り込む — main の変更を早めに取り込むことで、大きなコンフリクトを防げる
# feature ブランチで作業中に main の最新を取り込む git switch main git pull origin main git switch feature/my-work git merge main - 1つのブランチで長期間作業しない — 長く作業するほど main との差が広がり、コンフリクトが起きやすくなる
- チームで「誰がどのファイルを触るか」を共有する — 同じファイルを同時に編集しないよう調整する
- 小さい単位でコミット・マージする — 大きな変更を一気にマージするとコンフリクトが複雑になる
💻 やってみよう!
以下の手順でコンフリクトの発生から解消までを体験しましょう。
- main ブランチで greeting.txt を作成してコミット
git switch main echo "こんにちは" > greeting.txt git add greeting.txt git commit -m "挨拶ファイルを追加" - feature ブランチを作り、同じファイルを別の内容に変更
git switch -c feature/change-greeting echo "Hello" > greeting.txt git add greeting.txt git commit -m "挨拶を英語に変更" - main に戻ってマージ → コンフリクト発生
git switch main git merge feature/change-greeting greeting.txtを開いてマーカーを確認する- 好きな内容に書き換えて、マーカーを全て削除する
- 解消を記録する
git add greeting.txt git commit git log --onelineでマージコミットが記録されていることを確認
コンフリクトを解消できたら、このレッスンは完了です! 🎉
⚠️ よくあるミス
- マーカーを消し忘れてコミット —
<<<<<<<や=======がファイルに残ったままだとコードが壊れます。保存前にファイル内を検索して確認しましょう。 - コンフリクト中に別の作業を始める — 解消が完了するまで他のファイルを触らないこと。
git statusで「Unmerged paths」が消えるまで集中しましょう。 - コンフリクトを放置する — 時間が経つほど状況を忘れて解消が難しくなります。発生したらすぐに対処しましょう。
📌 まとめ
- ✅ コンフリクト = 同じファイルの同じ行を2つのブランチで変更したとき発生
- ✅ マーカー:
<<<<<<<(現在のブランチ)/=======(区切り)/>>>>>>>(マージ元) - ✅ 解消手順: ファイル修正 → マーカー削除 →
git add→git commit - ✅
git merge --abortでいつでもマージ前に戻れる - ✅ 予防: こまめに pull、小さい単位でマージ
このレッスンは役に立ちましたか?
フィードバックありがとうございます!
目次
⚠️ よくあるエラー
- TypeError: undefined is not an object (evaluating 'obj.name') — 存在しないオブジェクトのプロパティにアクセスしている
- TypeError: Cannot read properties of undefined (reading 'length') — undefinedに対して.lengthを呼んでいる
- SyntaxError: Identifier 'x' has already been declared — 同じ変数名を2回宣言している