Merge Conflict Resolution
Invariant Principles
- Synthesis over selection - Never pick sides. Create third option combining both intents.
--ours/--theirs= amputation. - Intent preservation - Both branches represent valuable parallel work. Understand WHY each changed before touching code.
- Surgical precision - Line-by-line edits, never wholesale replacement. >20 line changes require explicit approval.
- Evidence-based decisions - Tests exist for reasons. Deleting tested code = breaking expected behavior. Check first.
- Consent before loss - User must explicitly approve any code removal after understanding tradeoffs.
Why Synthesis Matters
Every line of code in a branch represents thought, debugging, and testing. Choosing --ours declares the other developer's work worthless. Choosing --theirs declares the current branch's work worthless. Both branches exist because both were needed.
If you cannot figure out how to synthesize, that is a signal to ask for help, not a signal to amputate.
Inputs
| Input | Required | Description |
|---|---|---|
conflict_files |
Yes | List of files with merge conflicts (from git status) |
merge_base |
Yes | Common ancestor commit (from git merge-base) |
ours_branch |
Yes | Current branch name |
theirs_branch |
Yes | Branch being merged |
Outputs
| Output | Type | Description |
|---|---|---|
resolution_plan |
Inline | Per-file synthesis strategy with base/ours/theirs analysis |
resolved_files |
Files | Conflict-free source files with synthesized changes |
verification_report |
Inline | Test results, lint status, behavior confirmation |
Reasoning Schema
Proceed only when synthesis strategy clear and surgical.
Conflict Classification
| Type | Files | Resolution |
|---|---|---|
| Mechanical | Lock files, changelogs, test fixtures | Auto: regenerate locks, chronological changelog merge |
| Binary | Images, compiled assets | Ask user to choose (synthesis impossible) |
| Complex | Source, configs, docs | 3-way analysis + synthesis required |
Resolution Workflow
- Detect: List conflicted files, classify mechanical/complex
- Analyze: 3-way diff (base vs ours vs theirs) per file
- Auto-resolve: Mechanical files only
- Plan: Synthesis strategy per complex file, present for approval
- Execute: Surgical edits after explicit approval
- Verify: Tests pass, lint clean, behavior preserved. If tests fail: do NOT declare done — identify which branch's behavior broke and revise synthesis.
Common Patterns
| Pattern | Resolution |
|---|---|
| Both modified same function | Merge both changes (logging AND error handling) |
| Delete vs modify | Apply modification to new location |
| Same name, different purpose | Rename to distinguish |
| Same name, same purpose | True merge into unified implementation |
Synthesis Example
Both branches modified the same validation function. Ours added rate limiting. Theirs added input sanitization.
<<<<<<< ours
function validateRequest(req) {
if (rateLimiter.isExceeded(req.ip)) {
throw new RateLimitError('Too many requests');
}
return processRequest(req);
}
=======
function validateRequest(req) {
const sanitized = sanitizeInput(req.body);
return processRequest({ ...req, body: sanitized });
}
>>>>>>> theirs
WRONG - Selecting "ours": Lost input sanitization. XSS vulnerability reintroduced.
WRONG - Selecting "theirs": Lost rate limiting. API now vulnerable to abuse.
CORRECT - Synthesis:
function validateRequest(req) {
if (rateLimiter.isExceeded(req.ip)) {
throw new RateLimitError('Too many requests');
}
const sanitized = sanitizeInput(req.body);
return processRequest({ ...req, body: sanitized });
}
// Rate limiting AND sanitization. Both authors' work honored.
The correct synthesis requires understanding WHY each branch made its change, not just WHAT changed. The 3-way analysis (Reasoning Schema) surfaces the "why."
Anti-Patterns
Red Flags (STOP immediately)
| Thought | Reality |
|---|---|
| "User said simplify, so use theirs" | Simplify = new third option simpler than EITHER |
| "Basically the same" | Conflict exists because they differ |
| "I'll adopt their approach" | --theirs with extra steps |
| "Tests need updating anyway" | Understand test purpose first |
| "This is cleaner" | Cleaner is not the goal. Preserving both intents is. |
Question Format
| Bad (binary, over-interpreted) | Good (surgical, specific) |
|---|---|
| "Ours or theirs?" | "What specifically needs to change?" |
| "Is master's better?" | "What from master should we adopt?" |
| "Should I simplify?" | "Which specific lines are unnecessary?" |
Binary questions get binary answers, then extrapolate to wholesale changes never approved.
Stealth Amputation Trap
Accidental --theirs without command:
- Ask binary question about complex code
- Get partial answer about ONE aspect
- Interpret as approval for EVERYTHING
Prevention: Approval for ONE aspect is NOT approval for all. Each deletion requires separate verification.
Acceptable Amputation Cases
Only with explicit user consent after tradeoff explanation:
- Binary files (no synthesis possible)
- Generated files (will regenerate)
- User explicitly requests after understanding loss
Plan Template
## Resolution: [filename]
**Base:** [original state]
**Ours:** [change + intent]
**Theirs:** [change + intent]
**Synthesis:** [how combining both]
**Risk:** [edge cases, concerns]
Self-Check
Before completing resolution:
- All conflicts resolved (no
<<<<<<<markers remain) - Tests pass (both ours and theirs functionality)
- Lint/build clean
- No tested code deleted without test updates
- Behavior from both branches present
- User approved specific changes (not extrapolated)
- Synthesis achieved, not selection
Mechanical Synthesis Test: For each resolved conflict, describe your resolution in one sentence. If that sentence contains ANY of these phrases, you are selecting, not synthesizing. Go back and rewrite:
- "kept X's version"
- "preferred Y's approach"
- "went with ours/theirs"
- "adopted the [branch] implementation"
- "chose the [simpler/cleaner/newer] version"
A valid synthesis sentence sounds like: "Combined ours' rate limiting with theirs' input sanitization into a single validation pipeline." It names contributions from BOTH sides.
If ANY item unchecked or synthesis test fails: STOP and fix.
Converted and distributed by TomeVault — claim your Tome and manage your conversions.