---
name: merge-assistant
description: Intelligent merge conflict resolution that analyzes, resolves conflicts automatically, and ensures safe merges.
isolation: worktree
---

# merge-assistant

Intelligent merge conflict resolution that analyzes, resolves conflicts automatically, and ensures safe merges.

## Usage

Ask me to help with merges. I'll resolve conflicts, ensure code quality, and complete merges safely.

## Interactive Merge Setup

### Merge Questions

```
Q1: Merge type?
   - Feature to develop
   - Develop to main
   - Hotfix to main
   - Release merge
   - Custom merge

Q2: Conflict strategy?
   - Favor incoming changes
   - Favor current changes
   - Smart resolution
   - Manual review

Q3: Testing after merge?
   - Full test suite
   - Smoke tests
   - Build only
   - Skip tests

Q4: Backup strategy?
   - Create backup branch
   - Stash changes
   - No backup
   - Tag before merge

Q5: Post-merge actions?
   - Delete source branch
   - Create release
   - Deploy to staging
   - Notify team
```

## Automated Merge Management

### Phase 1: Pre-Merge Analysis

```javascript
class MergeAnalyzer {
  async analyzeMerge(source, target) {
    const analysis = {
      commits: await this.getCommitDiff(source, target),
      files: await this.getFileDiff(source, target),
      conflicts: await this.predictConflicts(source, target),
      risk: await this.assessRisk(source, target),
      tests: await this.checkTestStatus(source),
    };

    // Generate merge report
    const report = this.generateReport(analysis);

    // Determine if safe to merge
    analysis.safeToMerge = this.isSafeToMerge(analysis);

    return analysis;
  }

  async predictConflicts(source, target) {
    const sourceChanges = await this.getChangedFiles(source);
    const targetChanges = await this.getChangedFiles(target);

    const potentialConflicts = [];

    for (const file of sourceChanges) {
      if (targetChanges.includes(file)) {
        const conflict = await this.analyzeFileConflict(file, source, target);
        if (conflict) {
          potentialConflicts.push(conflict);
        }
      }
    }

    return potentialConflicts;
  }

  assessRisk(analysis) {
    let risk = "low";

    if (analysis.conflicts.length > 10) risk = "high";
    else if (analysis.conflicts.length > 5) risk = "medium";

    if (analysis.files.length > 50) risk = "high";
    else if (analysis.files.length > 20) risk = "medium";

    return risk;
  }
}
```

### Phase 2: Smart Conflict Resolution

```javascript
// conflict-resolver.js
class ConflictResolver {
  async resolveConflicts(conflicts) {
    const resolutions = [];

    for (const conflict of conflicts) {
      console.log(`Resolving conflict in ${conflict.file}`);

      const resolution = await this.resolveConflict(conflict);
      resolutions.push(resolution);

      if (resolution.success) {
        await this.applyResolution(resolution);
      }
    }

    return resolutions;
  }

  async resolveConflict(conflict) {
    // Parse conflict markers
    const { ours, theirs, base } = this.parseConflict(conflict);

    // Try resolution strategies
    const strategies = [
      () => this.semanticMerge(ours, theirs, base),
      () => this.astMerge(ours, theirs, base),
      () => this.patternMerge(ours, theirs, base),
      () => this.heuristicMerge(ours, theirs, base),
    ];

    for (const strategy of strategies) {
      const result = await strategy();
      if (result.success) {
        return result;
      }
    }

    // If all fail, mark for manual resolution
    return {
      success: false,
      file: conflict.file,
      requiresManual: true,
      suggestion: this.generateSuggestion(conflict),
    };
  }

  semanticMerge(ours, theirs, base) {
    // For code files, use AST-based merging
    if (this.isCodeFile(ours.file)) {
      const ourAST = this.parseAST(ours.content);
      const theirAST = this.parseAST(theirs.content);
      const baseAST = this.parseAST(base.content);

      // Merge ASTs
      const mergedAST = this.mergeASTs(ourAST, theirAST, baseAST);

      // Generate code from merged AST
      const mergedCode = this.generateCode(mergedAST);

      return {
        success: true,
        content: mergedCode,
        method: "semantic",
      };
    }

    return { success: false };
  }

  astMerge(ours, theirs, base) {
    // Parse into AST
    const ast = {
      ours: parseTypeScript(ours),
      theirs: parseTypeScript(theirs),
      base: parseTypeScript(base),
    };

    // Find changes
    const ourChanges = diffAST(ast.base, ast.ours);
    const theirChanges = diffAST(ast.base, ast.theirs);

    // Apply non-conflicting changes
    let merged = ast.base;

    for (const change of [...ourChanges, ...theirChanges]) {
      if (!this.hasConflict(change, merged)) {
        merged = applyChange(merged, change);
      }
    }

    return {
      success: true,
      content: generateCode(merged),
      method: "ast",
    };
  }
}
```

### Phase 3: Safe Merge Execution

```javascript
// safe-merge.js
class SafeMerger {
  async performMerge(source, target, options = {}) {
    const { strategy = "recursive", backup = true, test = true } = options;

    // Create backup
    if (backup) {
      await this.createBackup(target);
    }

    try {
      // Start merge
      await exec(`git checkout ${target}`);
      await exec(`git merge ${source} --strategy=${strategy}`);

      // Check for conflicts
      const conflicts = await this.getConflicts();

      if (conflicts.length > 0) {
        console.log(`Found ${conflicts.length} conflicts`);

        // Resolve conflicts
        const resolver = new ConflictResolver();
        const resolutions = await resolver.resolveConflicts(conflicts);

        // Apply resolutions
        for (const resolution of resolutions) {
          if (resolution.success) {
            await fs.writeFile(resolution.file, resolution.content);
            await exec(`git add ${resolution.file}`);
          }
        }

        // Complete merge
        if (resolutions.every((r) => r.success)) {
          await exec("git commit --no-edit");
        } else {
          throw new Error("Some conflicts require manual resolution");
        }
      }

      // Run tests
      if (test) {
        const testResult = await this.runTests();
        if (!testResult.success) {
          throw new Error("Tests failed after merge");
        }
      }

      // Push changes
      await exec(`git push origin ${target}`);

      return { success: true };
    } catch (error) {
      // Rollback on failure
      if (backup) {
        await this.rollback(target);
      }
      throw error;
    }
  }

  async createBackup(branch) {
    const backupName = `backup/${branch}-${Date.now()}`;
    await exec(`git checkout -b ${backupName}`);
    await exec(`git checkout ${branch}`);
    console.log(`✅ Backup created: ${backupName}`);
  }

  async rollback(branch) {
    await exec("git merge --abort");
    await exec(`git reset --hard origin/${branch}`);
    console.log("✅ Rolled back to original state");
  }
}
```

### Phase 4: Merge Verification

```javascript
// merge-verifier.js
class MergeVerifier {
  async verifyMerge(source, target) {
    const checks = [
      this.checkNoConflictMarkers(),
      this.checkBuildSuccess(),
      this.checkTestsPass(),
      this.checkNoRegressions(),
      this.checkCodeQuality(),
    ];

    const results = await Promise.all(checks);

    return {
      success: results.every((r) => r.passed),
      details: results,
    };
  }

  async checkNoConflictMarkers() {
    const markers = ["<<<<<<<", "=======", ">>>>>>>"];
    const files = await exec("git ls-files");

    for (const file of files.split("\n")) {
      const content = await fs.readFile(file, "utf-8");
      for (const marker of markers) {
        if (content.includes(marker)) {
          return {
            passed: false,
            message: `Conflict marker found in ${file}`,
          };
        }
      }
    }

    return { passed: true };
  }

  async checkNoRegressions() {
    // Compare performance metrics
    const before = await this.getMetrics("before-merge");
    const after = await this.getMetrics("after-merge");

    const regressions = [];

    if (after.testTime > before.testTime * 1.2) {
      regressions.push("Test execution time increased by 20%");
    }

    if (after.bundleSize > before.bundleSize * 1.1) {
      regressions.push("Bundle size increased by 10%");
    }

    return {
      passed: regressions.length === 0,
      regressions,
    };
  }
}
```

### Phase 5: Post-Merge Actions

```javascript
// post-merge.js
class PostMergeActions {
  async execute(mergeResult) {
    const actions = [];

    // Update documentation
    if (mergeResult.filesChanged.includes("API")) {
      actions.push(this.updateAPIDocs());
    }

    // Generate changelog
    if (mergeResult.target === "main") {
      actions.push(this.generateChangelog());
    }

    // Notify team
    actions.push(this.notifyTeam(mergeResult));

    // Trigger CI/CD
    if (mergeResult.target === "main" || mergeResult.target === "develop") {
      actions.push(this.triggerPipeline());
    }

    // Clean up branches
    if (mergeResult.deleteSource) {
      actions.push(this.deleteBranch(mergeResult.source));
    }

    await Promise.all(actions);
  }

  async notifyTeam(result) {
    const message = `
🔀 Merge Complete

Source: ${result.source}
Target: ${result.target}
Files: ${result.filesChanged.length}
Conflicts resolved: ${result.conflictsResolved}
Tests: ${result.testsStatus}

View changes: ${result.url}
    `;

    await this.sendSlackNotification(message);
  }
}
```

## Example Output

```
🔀 Merge Assistant Started

Understanding merge requirements...
✓ Type: Feature to develop
✓ Strategy: Smart resolution
✓ Testing: Full suite
✓ Backup: Created
✓ Post-merge: Delete branch

Analyzing merge...
📊 Source: feature/user-dashboard
📊 Target: develop
📊 Commits: 15 ahead
📊 Files: 23 changed
📊 Risk: Medium

Predicting conflicts...
⚠️ 3 potential conflicts detected:
  - components/Dashboard.tsx
  - utils/api.ts
  - styles/main.css

Starting merge...
🔄 Merging feature/user-dashboard → develop

Resolving conflicts...
✅ Dashboard.tsx: Resolved (semantic merge)
✅ api.ts: Resolved (AST merge)
✅ main.css: Resolved (pattern merge)

Running verification...
✅ No conflict markers
✅ Build successful
✅ 195/195 tests passing
✅ No performance regressions
✅ Code quality maintained

Completing merge...
✅ Committed merge
✅ Pushed to origin
✅ Branch deleted

Post-merge actions...
✅ Documentation updated
✅ Changelog generated
✅ Team notified
✅ CI/CD triggered

📊 Merge Summary:
- Duration: 2m 15s
- Conflicts resolved: 3/3
- Auto-resolution rate: 100%
- Tests: All passing
- Status: Success

Next: Changes deployed to staging
```
