merge-resolver

Resolve merge conflicts by analyzing git history and commit intent. Use when PR has conflicts with base branch, can't merge due to conflicts, or need to fix merge conflicts systematically with session protocol validation.

model: claude-opus-4-5

$ Instalar

git clone https://github.com/rjmurillo/ai-agents /tmp/ai-agents && cp -r /tmp/ai-agents/.claude/skills/merge-resolver ~/.claude/skills/ai-agents

// tip: Run this command in your terminal to install the skill


name: merge-resolver version: 2.0.0 description: Resolve merge conflicts by analyzing git history and commit intent. Use when PR has conflicts with base branch, can't merge due to conflicts, or need to fix merge conflicts systematically with session protocol validation. license: MIT model: claude-opus-4-5 metadata: domains:

  • git
  • github
  • merge-conflicts
  • pr-maintenance type: workflow complexity: advanced adr: ADR-015

Merge Resolver

Resolve merge conflicts by analyzing git history and commit intent.

Triggers

Use this skill when you encounter:

  • resolve merge conflicts for PR #123
  • PR has conflicts with main
  • can't merge - conflicts detected
  • fix the merge conflicts in this branch
  • help me resolve conflicts for this pull request

Process

Phase 1: Context Gathering

StepActionVerification
1.1Fetch PR metadataJSON response received
1.2Checkout PR branchgit branch --show-current matches
1.3Attempt merge with baseConflict markers created
1.4List conflicted filesgit diff --name-only --diff-filter=U output

Phase 2: Analysis and Resolution

StepActionVerification
2.1Classify files (auto-resolvable vs manual)Classification logged
2.2Auto-resolve template/session filesAccept --theirs successful
2.3For manual: Run git blame, analyze intentCommit messages captured
2.4Apply manual resolutions per strategyConflict markers removed
2.5Stage all resolved filesgit diff --check clean

Phase 3: Validation (BLOCKING)

StepActionVerification
3.1Verify session log existsFile at .agents/sessions/
3.2Run session protocol validatorExit code 0
3.3Run markdown lintNo errors
3.4Commit merge resolutionCommit SHA recorded
3.5Push to remotePush successful

Workflow (Quick Reference)

  1. Fetch PR context - Get title, description, commits
  2. Identify conflicts - Find conflicted files in working directory
  3. Analyze each conflict - Use git blame and commit messages
  4. Determine intent - Classify changes by type
  5. Apply resolution - Keep, merge, or discard based on analysis
  6. Stage resolved files - Prepare for commit
  7. Validate session protocol - BLOCKING: Run validation before push

Step 1: Fetch PR Context

# Get PR metadata
gh pr view <number> --json title,body,commits,headRefName,baseRefName

# Checkout the PR branch
gh pr checkout <number>

# Attempt merge with base (creates conflict markers)
git merge origin/<base-branch> --no-commit

Step 2: Identify Conflicts

# List conflicted files
git diff --name-only --diff-filter=U

# Show conflict details
git status --porcelain | grep "^UU"

Step 3: Analyze Each Conflict

For each conflicted file:

# View the conflict
git diff --check

# Get blame for conflicting lines (base version)
git blame <base-branch> -- <file> | grep -n "<line-content>"

# Get blame for conflicting lines (head version)
git blame HEAD -- <file> | grep -n "<line-content>"

# Show commits touching this file on each branch
git log --oneline <base-branch>..<head-branch> -- <file>
git log --oneline <head-branch>..<base-branch> -- <file>

# View specific commit details
git show --stat <commit-sha>

Step 4: Determine Intent

Classify each side's changes:

TypeIndicatorsPriority
Bugfix"fix", "bug", "patch", "hotfix" in message; small, targeted changeHighest
Security"security", "vuln", "CVE" in messageHighest
Refactor"refactor", "cleanup", "rename"; no behavior changeMedium
Feature"feat", "add", "implement"; new functionalityMedium
Style"style", "format", "lint"; whitespace/formatting onlyLowest

Step 5: Apply Resolution

Decision Framework:

  1. Same intent, compatible changes - Merge both
  2. Bugfix vs feature - Bugfix wins, integrate feature around it
  3. Conflicting logic - Prefer the more recent or more tested change
  4. Style conflicts - Accept either, prefer consistency with surrounding code
  5. Deletions vs modifications - Investigate why; deletion usually intentional

Resolution Commands:

# Accept theirs (base branch)
git checkout --theirs <file>

# Accept ours (PR branch)
git checkout --ours <file>

# Manual edit then mark resolved
git add <file>

For manual resolution:

  1. Open file in editor
  2. Remove conflict markers (<<<<<<<, =======, >>>>>>>)
  3. Combine changes logically based on intent analysis
  4. Verify syntax and logic
  5. Stage the file

Step 6: Stage and Verify

# Stage all resolved files
git add <resolved-files>

# Verify no remaining conflicts
git diff --check

# Show staged changes
git diff --cached --stat

Step 7: Validate Session Protocol (BLOCKING)

MUST complete before pushing. This step prevents CI failures from incomplete session logs.

Why This Matters

Session protocol validation is a CI blocking gate. Pushing without completing session requirements causes:

  • CI failures with "MUST requirement(s) not met" errors
  • Wasted review cycles
  • Confusion about root cause (often misidentified as template sync issues)

Validation Steps

# 1. Ensure session log exists
SESSION_LOG=$(ls -t .agents/sessions/*.md 2>/dev/null | head -1)
if [ -z "$SESSION_LOG" ]; then
    echo "ERROR: No session log found. Create one before pushing."
    exit 1
fi

# 2. Run session protocol validator
pwsh scripts/Validate-SessionJson.ps1 -SessionLogPath "$SESSION_LOG"

# 3. If validation fails, fix issues before proceeding
if [ $? -ne 0 ]; then
    echo "ERROR: Session protocol validation failed."
    echo "Complete all MUST requirements in your session log before pushing."
    exit 1
fi

Session End Checklist (REQUIRED)

Before pushing, verify your session log contains:

ReqStepStatus
MUSTComplete session log (all sections filled)[ ]
MUSTUpdate Serena memory (cross-session context)[ ]
MUSTRun markdown lint[ ]
MUSTRoute to qa agent (feature implementation)[ ]
MUSTCommit all changes (including .serena/memories)[ ]
MUST NOTUpdate .agents/HANDOFF.md directly[ ]

Common Failures

ErrorCauseFix
E_TEMPLATE_DRIFTSession checklist outdatedCopy canonical checklist from SESSION-PROTOCOL.md
E_QA_EVIDENCEQA row checked but no report pathAdd QA report or use "SKIPPED: docs-only" for docs-only sessions
E_DIRTY_WORKTREEUncommitted changesStage and commit all files including .agents/

Resolution Strategies

See references/strategies.md for detailed patterns:

Code Conflicts:

  • Combining additive changes
  • Handling moved code
  • Resolving import conflicts
  • Dealing with deleted code
  • Conflicting logic resolution

Infrastructure Conflicts:

  • Package lock files (regenerate, don't merge)
  • Configuration files (JSON/YAML semantic merge)
  • Database migrations (renumber, preserve order)

Documentation Conflicts:

  • Numbered documentation (ADR, RFC) - renumber incoming to next available
  • Template-generated files - resolve in template, regenerate outputs
  • Rebase add/add conflicts - per-commit resolution during rebase

Auto-Resolution Script

For automated conflict resolution in CI/CD, use scripts/Resolve-PRConflicts.ps1:

# Resolve conflicts for a PR
pwsh .claude/skills/merge-resolver/scripts/Resolve-PRConflicts.ps1 \
    -PRNumber 123 \
    -BranchName "fix/my-feature" \
    -TargetBranch "main"

Auto-Resolvable Files

The following files are automatically resolved by accepting the target branch version:

PatternRationale
.agents/*Session artifacts, constantly changing
.serena/*Serena memories, auto-generated
.claude/skills/*/*.mdSkill definitions, main is authoritative
.claude/commands/*Command definitions, main is authoritative
.claude/agents/*Agent definitions, main is authoritative
templates/*Template files, main is authoritative
src/copilot-cli/*Platform agent definitions
src/vs-code-agents/*Platform agent definitions
src/claude/*Platform agent definitions
.github/agents/*GitHub agent configs
.github/prompts/*GitHub prompts
package-lock.json, yarn.lock, pnpm-lock.yamlLock files, regenerate from main

Script Output

Returns JSON:

{
  "Success": true,
  "Message": "Successfully resolved conflicts for PR #123",
  "FilesResolved": [".agents/HANDOFF.md"],
  "FilesBlocked": []
}

Exit Codes

CodeMeaning
0Success - conflicts resolved and pushed
1Failure - conflicts in non-auto-resolvable files

Security

ADR-015 compliance:

  • Branch name validation (prevents command injection)
  • Worktree path validation (prevents path traversal)
  • Handles both GitHub Actions runner and local environments

Verification

Success Criteria

CriterionEvidence
All conflicts resolvedgit diff --check returns empty
No merge markers remaingrep -r "<<<<<<" . returns nothing
Session protocol validValidate-SessionProtocol.ps1 exits 0
Markdown lint passesnpx markdownlint-cli2 exits 0
Push successfulRemote ref updated

Completion Checklist

  • All conflicted files staged (git add)
  • No UU status in git status --porcelain
  • Session log at .agents/sessions/YYYY-MM-DD-session-NN.md
  • Session End checklist completed
  • Serena memory updated
  • Merge commit created
  • Branch pushed to origin

Anti-Patterns

Anti-PatternWhy It FailsInstead
Push without session validationCI blocks with MUST violationsRun Validate-SessionProtocol.ps1 first
Manual edit of generated filesChanges lost on regenerationEdit template, run generator
Accept --ours for HANDOFF.mdBranch version often staleAccept --theirs (main is canonical)
Merge lock files manuallyJSON corruption, broken depsAccept base, regenerate with npm/yarn
Skip git blame analysisWrong intent inferenceAlways check commit messages
Resolve before fetchingMissing context, wrong baseAlways gh pr view first
Forget to stage .agents/Dirty worktree CI failureInclude all .agents/ changes

Extension Points

Custom Auto-Resolvable Patterns

Add patterns to $script:AutoResolvableFiles in Resolve-PRConflicts.ps1:

$script:AutoResolvableFiles += @(
    'your/custom/path/*',
    'another/pattern/**'
)

Custom Resolution Strategies

Create new entries in references/strategies.md for domain-specific conflicts:

  1. Document the conflict pattern
  2. Add investigation commands
  3. Define resolution priority
  4. Provide copy-paste commands

Integration with CI/CD

The script supports GitHub Actions via environment detection:

# In workflow YAML
- name: Resolve conflicts
  env:
    PR_NUMBER: ${{ github.event.pull_request.number }}
    HEAD_REF: ${{ github.head_ref }}
    BASE_REF: ${{ github.base_ref }}
  run: |
    pwsh .claude/skills/merge-resolver/scripts/Resolve-PRConflicts.ps1 \
      -PRNumber "$env:PR_NUMBER" \
      -BranchName "$env:HEAD_REF" \
      -TargetBranch "$env:BASE_REF"

Dry-Run Mode

Use -WhatIf for testing without side effects:

pwsh scripts/Resolve-PRConflicts.ps1 -PRNumber 123 -BranchName "fix/test" -WhatIf

Related

  • ADR-015: Security validation for branch names and paths
  • SESSION-PROTOCOL.md: Session end requirements (blocking gate)
  • strategies.md: Detailed resolution patterns for edge cases
  • merge-resolver-session-protocol-gap: Memory documenting root cause analysis