GitコンフリクトをClaudeに解決させる方法
git mergeやgit pull後にCONFLICTメッセージが出る- ファイルに
<<<<<<< HEAD、=======、>>>>>>> branch-nameのマーカーが入る git statusにboth modified:と表示されるファイルがある
原因1: 同じ行を異なるブランチで変更した
Section titled “原因1: 同じ行を異なるブランチで変更した”最もよくある原因。2つのブランチが同じ箇所を異なる方法で変更したとき、Gitは自動で解決できません。
原因2: ファイルを片方が削除し、もう片方が変更した
Section titled “原因2: ファイルを片方が削除し、もう片方が変更した”deleted by them: や deleted by us: と表示されます。どちらの意図を優先するか判断が必要です。
原因3: 長期間ブランチを放置した
Section titled “原因3: 長期間ブランチを放置した”main から長時間離れた作業ブランチは、main に多くの変更が積み重なり、コンフリクトが大量発生します。
※ブランチ: Gitでコードの変更履歴を分岐させる仕組み。本番コードに影響を与えずに新機能を開発できる。
ステップ1: 状況を把握する
Section titled “ステップ1: 状況を把握する”# コンフリクトしているファイルの一覧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つのバージョンの意図を理解した上で解決案を提示します。
// コンフリクトが発生したコード例<<<<<<< HEADexport 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> );}ステップ4: 解決後の確認
Section titled “ステップ4: 解決後の確認”# コンフリクトが全て解決されたか確認git status
# 解決したファイルをステージングgit add src/components/Header.tsx
# マージを完了git commit# (コミットメッセージはGitが自動生成)※コミット: Gitでファイルの変更を履歴として記録する操作。※マージ: Gitで別ブランチの変更を現在のブランチに統合すること。
よくある失敗と対処
Section titled “よくある失敗と対処”失敗: Claudeが一方のバージョンを完全に削除した
Section titled “失敗: Claudeが一方のバージョンを完全に削除した”コンフリクト解決で「両方の変更を生かしたい」のに、一方を削除してしまうことがあります。
防ぎ方:
「コンフリクトを解決してください。必ず両方のブランチの変更を保持してください。もし両立が難しい場合は、どちらを優先するか私に確認してください。」失敗: コンフリクトマーカーが残ったままコミットされた
Section titled “失敗: コンフリクトマーカーが残ったままコミットされた”# コンフリクトマーカーが残っていないか確認git diff --check
# コンフリクトマーカーを検索grep -r "<<<<<<< " src/grep -r "=======" src/grep -r ">>>>>>> " src/複雑なコンフリクトの戦略
Section titled “複雑なコンフリクトの戦略”戦略1: 両方のブランチの変更履歴をClaudeに見せる
Section titled “戦略1: 両方のブランチの変更履歴をClaudeに見せる”# 何が変更されたか、コミット単位で確認git log --oneline main..HEADgit 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: リベースでコンフリクトを小さくする”# マージの代わりにリベースを使う(コンフリクトを1コミットずつ解決)git rebase origin/main
# コンフリクトを解決後git add .git rebase --continue
# もしリベースを中断したい場合git rebase --abort※コンテキスト: Claudeが一度に記憶・参照できる会話・コードの範囲。上限を超えると古い情報が失われる。
定期的に main からマージする習慣
Section titled “定期的に main からマージする習慣”# 定期的に(少なくとも毎日)main の変更を取り込むgit fetch origingit merge origin/main作業範囲を小さくする
Section titled “作業範囲を小さくする”長期間の大きな機能ブランチほどコンフリクトが起きやすくなります。Feature Flag を使って小さなPRを頻繁にマージする戦略が有効です。