Skip to content

GitコンフリクトをClaudeに解決させる方法

  • git mergegit pull 後に CONFLICT メッセージが出る
  • ファイルに <<<<<<< HEAD=======>>>>>>> branch-name のマーカーが入る
  • git statusboth modified: と表示されるファイルがある

原因1: 同じ行を異なるブランチで変更した

Section titled “原因1: 同じ行を異なるブランチで変更した”

最もよくある原因。2つのブランチが同じ箇所を異なる方法で変更したとき、Gitは自動で解決できません。

原因2: ファイルを片方が削除し、もう片方が変更した

Section titled “原因2: ファイルを片方が削除し、もう片方が変更した”

deleted by them:deleted by us: と表示されます。どちらの意図を優先するか判断が必要です。

原因3: 長期間ブランチを放置した

Section titled “原因3: 長期間ブランチを放置した”

main から長時間離れた作業ブランチは、main に多くの変更が積み重なり、コンフリクトが大量発生します。

ブランチ: Gitでコードの変更履歴を分岐させる仕組み。本番コードに影響を与えずに新機能を開発できる。
Terminal window
# コンフリクトしているファイルの一覧
git status
# コンフリクトの内容を確認
git diff
# どのブランチからマージしようとしているか確認
git log --oneline HEAD...MERGE_HEAD

ステップ2: Claudeにコンフリクト解決を依頼する

Section titled “ステップ2: Claudeにコンフリクト解決を依頼する”

Claude Codeに以下のように依頼します。

シンプルなコンフリクトの場合:

「git merge でコンフリクトが発生しました。
src/components/Header.tsx を確認して、解決してください。
背景: 私のブランチではナビゲーションメニューを追加しました。
main ブランチではレスポンシブ対応が入ったようです。
両方の変更を保持する方向で解決してください。」

複数ファイルのコンフリクトの場合:

「git pull origin main でコンフリクトが発生しました。
git status の結果を見ながら、1ファイルずつ解決していきましょう。
まず影響の小さいファイルから始めて、複雑なものは私に確認してください。」

ステップ3: Claudeの解決案を確認する

Section titled “ステップ3: Claudeの解決案を確認する”

Claudeはコンフリクトマーカーを解析して、2つのバージョンの意図を理解した上で解決案を提示します。

// コンフリクトが発生したコード例
<<<<<<< HEAD
export function Header({ showMenu = true }: HeaderProps) {
const [isMenuOpen, setIsMenuOpen] = useState(false);
return (
<header>
<Logo />
{showMenu && <NavigationMenu isOpen={isMenuOpen} onToggle={setIsMenuOpen} />}
</header>
);
}
=======
export function Header({ className }: HeaderProps) {
return (
<header className={cn('sticky top-0 z-50', className)}>
<Logo />
</header>
);
}
>>>>>>> main
// Claudeが提案する解決案:
export function Header({ showMenu = true, className }: HeaderProps) {
const [isMenuOpen, setIsMenuOpen] = useState(false);
return (
<header className={cn('sticky top-0 z-50', className)}>
<Logo />
{showMenu && <NavigationMenu isOpen={isMenuOpen} onToggle={setIsMenuOpen} />}
</header>
);
}
Terminal window
# コンフリクトが全て解決されたか確認
git status
# 解決したファイルをステージング
git add src/components/Header.tsx
# マージを完了
git commit
# (コミットメッセージはGitが自動生成)
コミット: Gitでファイルの変更を履歴として記録する操作。マージ: Gitで別ブランチの変更を現在のブランチに統合すること。

失敗: Claudeが一方のバージョンを完全に削除した

Section titled “失敗: Claudeが一方のバージョンを完全に削除した”

コンフリクト解決で「両方の変更を生かしたい」のに、一方を削除してしまうことがあります。

防ぎ方:

「コンフリクトを解決してください。
必ず両方のブランチの変更を保持してください。
もし両立が難しい場合は、どちらを優先するか私に確認してください。」

失敗: コンフリクトマーカーが残ったままコミットされた

Section titled “失敗: コンフリクトマーカーが残ったままコミットされた”
Terminal window
# コンフリクトマーカーが残っていないか確認
git diff --check
# コンフリクトマーカーを検索
grep -r "<<<<<<< " src/
grep -r "=======" src/
grep -r ">>>>>>> " src/

戦略1: 両方のブランチの変更履歴をClaudeに見せる

Section titled “戦略1: 両方のブランチの変更履歴をClaudeに見せる”
Terminal window
# 何が変更されたか、コミット単位で確認
git log --oneline main..HEAD
git log --oneline HEAD..main
# 特定ファイルの変更履歴
git log -p --follow src/api/users.ts

この出力をClaudeに見せると、「なぜその変更が行われたか」のコンテキストを理解して解決できます。

戦略2: インタラクティブな解決

Section titled “戦略2: インタラクティブな解決”

複雑な場合は1ファイルずつ対話的に進めます。

「src/api/users.ts のコンフリクトを見てください。
ただし自動解決しないで。まず両方のバージョンの意図を説明して、
その後で解決案を提示してください。」

戦略3: リベースでコンフリクトを小さくする

Section titled “戦略3: リベースでコンフリクトを小さくする”
Terminal window
# マージの代わりにリベースを使う(コンフリクトを1コミットずつ解決)
git rebase origin/main
# コンフリクトを解決後
git add .
git rebase --continue
# もしリベースを中断したい場合
git rebase --abort
コンテキスト: Claudeが一度に記憶・参照できる会話・コードの範囲。上限を超えると古い情報が失われる。

定期的に main からマージする習慣

Section titled “定期的に main からマージする習慣”
Terminal window
# 定期的に(少なくとも毎日)main の変更を取り込む
git fetch origin
git merge origin/main

長期間の大きな機能ブランチほどコンフリクトが起きやすくなります。Feature Flag を使って小さなPRを頻繁にマージする戦略が有効です。