merge-conflict-resolution
Detect, classify (porcelain status; complexity: trivial, semantic, structural, delete-modify), and resolve git merge conflicts through per-file strategy selection (accept-ours, accept-theirs, manual-m
Files1
View on GitHubSKILL.mdplugins/flow/skills/merge-conflict-resolution/SKILL.md
GitHubMerge Conflict Resolution
Contract
Iron law: never silently drop changes — every resolution accounts for both sides, documents any excluded lines, and asks the user rather than guessing. Invoked by /flow:resolve Phase 1 (detect and classify), Phase 2 (per-file strategy plan), Phase 3 (resolve hunks), and Phase 4 (marker audit, complete merge/rebase, quality checks). Returns, per conflicted file: type (UU/AA/UD/DU/AU/UA), complexity (trivial/semantic/structural/delete-modify), strategy (accept-ours/accept-theirs/manual-merge/ask-user), hunk count, and result, plus the quality outcome. Permitted skips: none — trivial files auto-resolve only when conflictResolution.autoResolveTrivial is true; delete-modify and competing hunks always go to the user.
Detect
git diff --name-only --diff-filter=U
git status --porcelain
Settings: conflictResolution.autoResolveTrivial (default true), conflictResolution.maxConflictFiles (default 20). Above the limit, AskUserQuestion: proceed anyway, or abort and rebase in smaller steps.
Classify
| Status | Type |
|---|---|
| UU | Content — both sides modified the same file |
| AA | Add-add — both sides added the same name |
| UD | Delete-modify — ours deleted, theirs modified |
| DU | Delete-modify — theirs deleted, ours modified |
| AU / UA | Rename collision |
| Complexity | Meaning |
|---|---|
| trivial | Non-overlapping changes in different sections |
| semantic | Both sides change the same logical unit |
| structural | One side refactored (moved code, renamed, restructured) |
| delete-modify | One side deleted what the other modified |
Strategy
| Strategy | When | Autonomy |
|---|---|---|
| accept-ours | Their change is superseded by ours | Tier 1 for trivial |
| accept-theirs | Our change is superseded by theirs | Tier 1 for trivial |
| manual-merge | Both changes are needed | Tier 2 — show rationale |
| rebase | Linear history wanted, few conflicts | Tier 2 — show rationale |
Create one task per file (type, complexity, strategy, hunks) and display the Conflict Analysis table. Trivial files auto-proceed when autoResolveTrivial is true; semantic, structural, and delete-modify files show both sides and the proposed strategy via AskUserQuestion first. Never "take ours for everything" — analyze each conflict individually, and verify that "identical" changes really are identical.
Resolve Each Hunk
- Parse the ours block (
<<<<<<<to=======) and theirs block (=======to>>>>>>>). - Identify each side's intent.
- Compatible (different imports, non-overlapping logic) → combine both. Competing (two implementations of the same thing) →
AskUserQuestionshowing both sides with context. - Write the resolved content with all markers removed;
grep -n '<<<<<<<\|=======\|>>>>>>>' "$FILE"must return nothing. git add "$FILE"; mark the task completed.
Delete-modify: show what was deleted and what was modified; offer keep-modified, accept-deletion, or keep-modified-at-new-location (if the file moved); wait for the decision. Never auto-resolve.
Verify (Phase 4)
- Repo-wide marker audit — must return nothing; any hit goes back to resolving that file:
grep -rn '<<<<<<<\|=======\|>>>>>>>' --include='*' . 2>/dev/null | grep -v '.git/' | grep -v 'node_modules/' - Complete:
git commit --no-edit(merge) orgit rebase --continue(rebase). - Run lint, tests, typecheck (commands from capability-discovery). Failures →
debugging-patterns, up toclosedLoop.maxBuildIterations. - Review the resolution diff (
git diff HEAD~1 --stat) — passing tests do not prove semantic correctness. Every file in the conflict list is verified or its skip explicitly documented; "this file isn't important" is not a reason.