Git Resolve Conflicts スキル
Instructions
このスキルはマージコンフリクトを分析し、解消案を生成・提示して、ユーザー承認後に適用するワークフローを提供します。
重要: git コマンドは作業ディレクトリで直接実行する。git -C は使用禁止。
処理フロー
Step 1: コンフリクト状態の検出
以下の git コマンドを並列で実行し、コンフリクト状態を把握する:
git status --porcelain # UU/AA/DD/AU/UA/DU/UD マーカー検出
git diff --name-only --diff-filter=U # unmerged ファイル一覧
コンフリクト種類の判定:
| 判定ファイル | 種類 | 対応 |
|---|---|---|
MERGE_HEAD が存在 | merge コンフリクト | 対応 |
REBASE_HEAD が存在 | rebase コンフリクト | 非対応、エラーメッセージ表示 |
CHERRY_PICK_HEAD が存在 | cherry-pick コンフリクト | 非対応、エラーメッセージ表示 |
| いずれも存在しない | コンフリクト状態ではない | エラー終了 |
rebase/cherry-pick コンフリクトの場合は以下を表示:
現在は rebase/cherry-pick コンフリクトの自動解消には対応していません。
手動で解消するか、以下のコマンドで中止してください:
- git rebase --abort
- git cherry-pick --abort
Step 2: 復元手段の確認
マージコンフリクト中は git merge --abort でいつでもマージ前の状態に完全復元できる。
別途バックアップを取る必要はない(git stash はコンフリクト状態では実行不可)。
以降の全ステップで、ユーザーが中止を選択した場合のロールバック手段として
git merge --abort が利用可能であることを常に案内する。
Step 3: コンフリクト分析(履歴ベース)
各コンフリクトファイルについて以下を実行:
3a. ブランチ分岐点の特定
git merge-base HEAD MERGE_HEAD
分岐点を起点に、両ブランチの変更を時系列で把握する。
3b. 両ブランチの変更履歴を取得(並列実行)
# ours 側(現在のブランチ = main)の変更履歴
git log <merge-base>..HEAD --oneline --follow -- <file>
# theirs 側(マージ元ブランチ)の変更履歴
git log <merge-base>..MERGE_HEAD --oneline --follow -- <file>
# 各コミットの詳細(変更内容の把握に必要な場合)
git show <commit-hash> -- <file>
3c. 時系列と変更意図の分析
以下の観点で両側の変更を分析する:
| 分析項目 | 確認内容 |
|---|---|
| 時系列 | どちらの変更が先か、どういう順序で変更されたか |
| 変更の種類 | 追加 / 修正 / 削除 / リファクタリング |
| 変更の意図 | コミットメッセージから目的を読み取る |
| 依存関係 | 一方の変更が他方の前提になっていないか |
3d. Read でファイル内容を読み取り
コンフリクトマーカー(<<<<<<<, =======, >>>>>>>)を解析し、
ours 側と theirs 側の具体的なコード差分を把握する。
3e. 解消戦略の決定
履歴分析の結果に基づき、以下のパターンで解消戦略を決定:
| パターン | 典型例 | 解消戦略 |
|---|---|---|
| 追加 vs 追加 | 両ブランチで別の関数/import を追加 | 両方残す(統合) |
| 修正 vs 追加 | 一方が既存コードを修正、他方が新コードを追加 | 両方残す(位置を調整) |
| 修正 vs 修正(同一箇所) | 同じ関数を別々に修正 | 時系列と意図を加味して統合案を生成 |
| 削除 vs 修正 | 一方がコードを削除、他方が同じコードを修正 | ユーザー判断を求める |
| リファクタ vs 機能追加 | 一方がリネーム/移動、他方が機能追加 | リファクタを基盤に機能追加を適用 |
重要: 元ブランチから切ったブランチのコミットと、 元ブランチの履歴変更・追加による衝突が最も多い。 この場合、両方の変更は独立した意図を持つことが多く、 「両方残す」が正しい解消になるケースが多い。
Step 4: 解消案の生成と分類
コンフリクトファイルを2カテゴリに分類:
| カテゴリ | 判定基準 | 確認方式 |
|---|---|---|
| 自明な解消 | 片方が追加のみ / 空白差分のみ / import 文の追加のみ | 一括提示・一括承認 |
| 要判断の解消 | 両方にビジネスロジック変更 / 削除と変更の競合 | 個別提示・個別承認 |
判定に迷った場合は「要判断」に分類する(安全側に倒す)。
各コンフリクトについて解消案を生成:
- 両方の変更を統合する案(可能な場合)
- 一方を優先する案
- diff 形式で解消前後を明示
Step 5: ユーザー確認(AskUserQuestion)
自明グループ
自明な解消が存在する場合、まとめて提示:
- 解消案の一覧を表示
- AskUserQuestion で確認:
- header: "自明な解消"
- question: "以下の自明なコンフリクト解消を一括で適用してよいですか?"
- options:
- "はい、一括適用": 全て適用
- "いいえ、中止": マージ全体を中止
要判断グループ
要判断の解消はファイルごとに以下のフォーマットで提示:
## <ファイル名> のコンフリクト解消案
### 変更履歴の概要
- **分岐点**: <merge-base のハッシュ> (<日時>)
- **ours 側 (main)**: N コミット
- <hash> <message> (<日時>)
- ...
- **theirs 側 (<branch>)**: N コミット
- <hash> <message> (<日時>)
- ...
### コンフリクト箇所
- 箇所 N: 行 XX-YY
- ours: <変更の説明>
- theirs: <変更の説明>
- パターン: 追加 vs 追加
### 解消案
<diff 形式で解消後のコードを表示>
### 判断根拠
<時系列と内容に基づく解消理由の説明>
- AskUserQuestion で確認:
- header: "コンフリクト解消"
- question: "<ファイル名> のコンフリクト解消案を適用しますか?"
- options:
- "はい、適用": この解消案を適用
- "修正して適用": ユーザーが修正内容を指示
- "スキップ": このファイルはスキップ
- "中止": マージ全体を中止
中止の場合
ユーザーが中止を選択した場合:
git merge --abort
元のブランチに戻り、処理を終了する。
Step 6: 適用
承認された解消案をファイルに書き込む:
- Edit ツールで各ファイルのコンフリクトマーカーを解消後の内容に置換
- 解消済みファイルをステージング:
git add <resolved-files>
- 適用後の確認:
git status
git diff --staged
結果をユーザーに提示し、以下を明示:
- 解消されたファイルの一覧
- スキップされたファイルがある場合はその旨
- ロールバック手順: まだ
git merge --abortが可能かどうか
Step 7: 完了報告
解消結果のサマリーを表示:
- 解消したファイル数 / コンフリクト数
- コミット前であれば
git merge --abortでロールバック可能
次のステップを案内:
- merge スキルから呼ばれた場合: マージコミット作成に戻る
- 直接呼ばれた場合:
git commitでマージ完了を促す
安全規則
必須
- コンフリクト解消の適用前にユーザー承認を必須とする
- 全ての解消案を提示してからユーザーに判断を委ねる
絶対禁止
- ユーザー承認なしでのコンフリクト解消適用
git merge --abort以外の破壊的操作- git config の更新
--forceオプション付きの操作
特別警告
以下のファイルにコンフリクトがある場合は特別警告を表示:
.env,.env.*- 環境変数ファイルcredentials.json,secrets.*- 機密情報ファイル*.key,*.pem,*.cert- 証明書・鍵ファイル
警告メッセージ:
⚠ 機密ファイルにコンフリクトが検出されました: <ファイル名>
機密情報が含まれる可能性があります。解消案の内容を慎重に確認してください。
Examples
正常なコンフリクト解消フロー
# Step 1: コンフリクト検出
$ git status --porcelain
UU src/config.ts
UU src/utils.ts
# Step 2: 復元手段の確認
# git merge --abort でいつでもマージ前の状態に完全復元可能
# Step 3: 履歴ベースのコンフリクト分析
$ git merge-base HEAD MERGE_HEAD
abc1234
$ git log abc1234..HEAD --oneline --follow -- src/config.ts
def5678 feat: 新しい認証モジュールの import を追加
$ git log abc1234..MERGE_HEAD --oneline --follow -- src/config.ts
ghi9012 feat: ログモジュールの import を追加
$ git log abc1234..HEAD --oneline --follow -- src/utils.ts
jkl3456 fix: formatDate にタイムゾーン対応を追加
$ git log abc1234..MERGE_HEAD --oneline --follow -- src/utils.ts
mno7890 refactor: formatDate のフォーマット文字列を変更
📋 コンフリクト分析結果:
1. src/config.ts (自明)
- パターン: 追加 vs 追加(import 文)
- ours: 認証モジュール import 追加 (def5678)
- theirs: ログモジュール import 追加 (ghi9012)
- 解消戦略: 両方残す(独立した追加)
2. src/utils.ts (要判断)
- パターン: 修正 vs 修正(同一箇所)
- ours: タイムゾーン対応追加 (jkl3456)
- theirs: フォーマット文字列変更 (mno7890)
- 時系列: ours が先、theirs が後
- 解消戦略: 両方の変更を統合案として生成
# Step 5: ユーザー確認
[自明な解消] src/config.ts の import 統合を一括適用してよいですか?
→ はい、一括適用
## src/utils.ts のコンフリクト解消案
### 変更履歴の概要
- 分岐点: abc1234 (2026-02-10)
- ours 側 (main): 1 コミット
- jkl3456 fix: formatDate にタイムゾーン対応を追加 (2026-02-12)
- theirs 側 (feature/logging): 1 コミット
- mno7890 refactor: formatDate のフォーマット文字列を変更 (2026-02-14)
### コンフリクト箇所
- 箇所 1: 行 15-25
- ours: タイムゾーンパラメータ追加と Intl.DateTimeFormat 使用
- theirs: フォーマット文字列を ISO 8601 準拠に変更
- パターン: 修正 vs 修正(同一箇所)
### 解消案
(diff 形式で統合後のコードを表示)
### 判断根拠
両コミットは独立した目的(タイムゾーン対応 / フォーマット標準化)。
theirs のフォーマット変更を基盤に、ours のタイムゾーン対応を適用。
→ はい、適用
# Step 6: 適用
$ git add src/config.ts src/utils.ts
$ git status
$ git diff --staged
# Step 7: 完了報告
コンフリクト解消完了
- 解消ファイル: 2/2
- コミット前であれば git merge --abort でロールバック可能
- 次のステップ: git commit でマージを完了してください
merge スキルからの呼び出し
⚠ マージ中にコンフリクトが発生しました。
git-resolve-conflicts スキルでコンフリクト解消を実行します。
[コンフリクト解消フローを実行]
✅ コンフリクト解消完了
マージコミットの作成に進みます。
コンフリクト解消の中止
# ユーザーが中止を選択
$ git merge --abort
マージを中止しました。元のブランチに戻ります。
