コンフリクト解消 — 同じ場所を同時に変えた時どうする
学習目標
このレッスンを終えると、次のことができるようになります。
- コンフリクトが起きる仕組みを 1 枚の図で説明できる
- conflict マーカー (
<<<<<<<) の読み方を理解できる - 自分でコンフリクトを解消し、merge を完了できる
- AI Agent にコンフリクト解消を任せていい場面と任せちゃダメな場面を判別できる
コンフリクトはなぜ起きるか
コンフリクト (conflict、衝突) は、2 つのブランチが同じファイルの同じ行を別の内容に変えた時に発生する。
gitGraph
commit id: "A"
branch feature
checkout feature
commit id: "B: login.py の 10 行目を「赤」に"
checkout main
commit id: "C: login.py の 10 行目を「青」に"
checkout main
merge feature id: "?: 赤 vs 青 どちらを残す?"
Git は機械的判断できないのでここは人間が決めてくださいと止める。
コンフリクトの体験 — ハンズオン
セットアップ
mkdir conflict-demo && cd conflict-demo
git init
echo "color: green" > config.txt
git add . && git commit -m "初期"
git switch -c feature/red
echo "color: red" > config.txt
git commit -am "色を赤に"
git switch main
echo "color: blue" > config.txt
git commit -am "色を青に"
# main で feature/red を merge してみる
git merge feature/red
すると Git が止まる:
Auto-merging config.txt
CONFLICT (content): Merge conflict in config.txt
Automatic merge failed; fix conflicts and then commit the result.
コンフリクト中のファイルを開く
config.txt の中身はこうなっている:
<<<<<<< HEAD
color: blue
=======
color: red
>>>>>>> feature/red
これが conflict マーカー。3 つの記号で区切られている:
| マーカー | 意味 |
|---|---|
<<<<<<< HEAD から ======= まで |
現在のブランチ (main) の内容 |
======= から >>>>>>> feature/red まで |
取り込もうとしているブランチの内容 |
解消手順
- どちらを残すか決める (または両方を組み合わせる)
- conflict マーカーを全部消す
- 正しい内容だけを残す
例えば「両方の色を混ぜて紫にする」なら:
color: purple
(マーカーは完全削除)
- 解消したファイルをステージング
git add config.txt
- merge を完了
git commit # 自動でメッセージが入る
# あるいは
git commit -m "Merge feature/red — 色を統合"
解消のコツ
コツ 1: 焦らず git status を読む
git status
# 両方が変更: config.txt
# 修正されていない衝突: 1 件
何が衝突しているか、まず状態を見る。
コツ 2: 大量にコンフリクトしたら一旦中断する
git merge --abort
--abort で merge 前の状態に戻れる。冷静になってから再挑戦できる。
コツ 3: 視覚化ツールを使う
VS Code / Cursor は <<<<<<< を検出して 「Accept Current Change / Accept Incoming Change / Accept Both Changes」 ボタンを表示してくれる。CLI で手編集するより事故が少ない。
flowchart LR
F[conflict 発生] --> V[VS Code で<br/>config.txt を開く]
V --> B[コンフリクト箇所に<br/>ボタンが表示]
B --> C[Accept Current/Incoming/Both]
C --> S[git add]
S --> M[git commit で merge 完了]
コツ 4: コンフリクトしたファイルを一覧で出す
git diff --name-only --diff-filter=U
U = Unmerged (未解決)。修正対象がパッと分かる。
AI Agent にコンフリクト解消を任せていいか?
短い答え: 単純な構文的コンフリクトは AI が解いてよいが、意味の判断が必要な場合は必ず人間が確認する。
AI 任せでよい
| 例 | なぜ OK か |
|---|---|
| import 文の追加が両ブランチで起きた | 両方を残して並べるだけ |
| 行末コンマの違い | フォーマッタが整える |
| 別ファイルの全く別の機能 | 重複なし |
人間が必ず判断
| 例 | なぜ要 |
|---|---|
| 同じ関数のロジックを両方が変えた | どちらの仕様が正なのか業務判断 |
| 設定値 (料金・しきい値) の変更 | 経営判断・確認が必要 |
| セキュリティ関連 (認証・権限) | 間違うと脆弱性 |
| マイグレーション (DB 構造変更) | データ破損リスク |
AI への指示例:
このコンフリクトは認証ロジックなので、自動で解消せず、両方の差分を要約して人間に判断を仰いでください。
コンフリクト予防 — 「小さく早く同期する」
flowchart TB
A[長期 feature ブランチ] --> B{main と<br/>同期してる?}
B -->|何日も同期してない| C[main の変更が溜まる]
C --> D[merge で<br/>大量コンフリクト]
D --> E[解消が大事故]
B -->|毎日 1 回 同期| F[main の変更を吸収]
F --> G[小さなコンフリクトを<br/>こまめに解消]
G --> H[最終 merge は楽]
毎日の git fetch && git rebase origin/main (または git merge origin/main) を習慣にする。
振り返り
- コンフリクトは「同じ場所を別内容に変えた」時に起きる。Git は判断できないので人間が決める
<<<<<<< HEAD ... ======= ... >>>>>>> featureのマーカーを読み解いて手編集- 解消したら
git add→git commitで完了 - 業務判断が要るコンフリクトは AI 任せにせず、人間が確認
- 予防は「小さく頻繁に同期する」
次のレッスンでは、ailms で推奨している ブランチ運用ルール を学びます。
参考リンク
- Pro Git「マージコンフリクト」: https://git-scm.com/book/ja/v2/Git-のブランチ機能-ブランチとマージの基本
- VS Code のマージ コンフリクト UI: https://code.visualstudio.com/docs/sourcecontrol/overview#_merge-conflicts
全 14 レッスンを、登録なしで無料で読めます。