G

Git Conflict Resolver

Intelligently resolves git merge conflicts by understanding the intent of both branches, preserving functionality from each side.

SkillClipticsgit workflowv1.0.0MIT
0 views0 copies

Git Conflict Resolver

Systematically resolve merge conflicts by analyzing both sides of the conflict, understanding intent, and producing correct merged output with verification.

When to Use This Template

Choose Git Conflict Resolver when:

  • You have merge conflicts after git merge, git rebase, or git cherry-pick
  • Multiple team members edited the same files and you need intelligent merging
  • Complex conflicts span multiple functions or interrelated files
  • You want automated conflict resolution with human-readable explanations

Consider alternatives when:

  • Conflicts are trivial (single-line changes in different sections)
  • You need to resolve conflicts in binary files (use the version you want to keep)
  • The conflict is a complete rewrite requiring manual decision-making

Quick Start

# .claude/skills/git-conflict-resolver.yml name: git-conflict-resolver description: Resolve git merge conflicts with analysis prompt: | Resolve the merge conflicts in the specified files. For each conflict: 1. Show both sides (ours and theirs) 2. Analyze the intent of each change 3. Determine the correct resolution: - If changes are independent: combine both - If changes conflict logically: choose the correct one - If both modify the same logic: create a merged version 4. Explain your resolution reasoning 5. Verify the resolved code compiles/parses correctly Never silently drop changes from either side.

Example invocation:

claude "Resolve all merge conflicts in the current branch"

Sample resolution output:

Conflict 1: src/services/userService.ts (lines 45-62)

OURS (feature/auth-v2):
  Added token refresh logic with 15-min expiry

THEIRS (main):
  Added rate limiting to auth endpoints

Resolution: COMBINE BOTH — changes are independent
  Kept token refresh logic AND rate limiting
  Moved rate limit check before token refresh
  for correct execution order.

Conflict 2: src/models/User.ts (lines 12-18)

OURS: Changed `role` type from string to enum
THEIRS: Added `permissions` field alongside `role`

Resolution: MERGE — keep enum change + add permissions
  Applied enum type to `role` AND added `permissions` field

Core Concepts

Conflict Resolution Strategies

Conflict TypeStrategyExample
Independent additionsCombine bothTwo new functions in same file
Same line, different changeAnalyze intent, pick correctBoth fixed same bug differently
Structural refactor vs. editApply edit to refactored structureOne branch renamed, other edited
Import conflictsMerge import listsBoth added different imports
Config/version conflictsUse latest or combinePackage.json version bumps

Conflict Analysis Process

# Step 1: Identify all conflicts git diff --name-only --diff-filter=U # Step 2: View conflict details for each file git diff --check # Shows conflict markers # Step 3: Understand the history of each side git log --oneline --left-right HEAD...MERGE_HEAD -- conflicted-file.ts # Step 4: See what each side changed independently git diff HEAD...MERGE_HEAD -- conflicted-file.ts # Their changes git diff MERGE_HEAD...HEAD -- conflicted-file.ts # Our changes

Automated Conflict Parsing

interface ConflictBlock { file: string; startLine: number; endLine: number; ours: string; // Between <<<<<<< and ======= theirs: string; // Between ======= and >>>>>>> oursRef: string; // Branch name from <<<<<<< marker theirsRef: string; // Branch name from >>>>>>> marker } function parseConflicts(fileContent: string, filePath: string): ConflictBlock[] { const conflicts: ConflictBlock[] = []; const lines = fileContent.split('\n'); let i = 0; while (i < lines.length) { if (lines[i].startsWith('<<<<<<<')) { const oursRef = lines[i].replace('<<<<<<< ', ''); const startLine = i + 1; const oursLines: string[] = []; const theirsLines: string[] = []; let inTheirs = false; i++; while (i < lines.length && !lines[i].startsWith('>>>>>>>')) { if (lines[i].startsWith('=======')) { inTheirs = true; } else if (inTheirs) { theirsLines.push(lines[i]); } else { oursLines.push(lines[i]); } i++; } const theirsRef = lines[i]?.replace('>>>>>>> ', '') || ''; conflicts.push({ file: filePath, startLine, endLine: i + 1, ours: oursLines.join('\n'), theirs: theirsLines.join('\n'), oursRef, theirsRef }); } i++; } return conflicts; }

Safe Resolution Workflow

# Before resolving: create a backup git stash push -m "backup before conflict resolution" # Resolve conflicts (manually or with tool) # ... edit files ... # After resolving: verify git diff --staged # Review resolved changes npm run typecheck # Verify types npm test # Verify tests pass # Complete the merge git add . git commit # Uses auto-generated merge commit message

Configuration

OptionTypeDefaultDescription
strategystring"analyze"Resolution approach: analyze, ours, theirs, combine
verifyAfterbooleantrueRun typecheck/lint after resolution
showDiffbooleantrueShow before/after diff for each resolution
autoStagebooleanfalseAutomatically git add resolved files
backupBranchbooleantrueCreate backup branch before resolving
ignoreWhitespacebooleantrueIgnore whitespace-only conflicts

Best Practices

  1. Understand both sides before resolving — Read the git log for both branches to understand the intent behind each change. A line change might be part of a larger refactor, and resolving the conflict without understanding the broader context can break the refactor's consistency.

  2. Pull and rebase frequently to minimize conflicts — The longer a feature branch diverges from main, the more conflicts it accumulates. Rebase onto main daily or at least before creating a PR. Small, frequent integrations produce fewer and simpler conflicts.

  3. Never blindly accept one side — Using git checkout --ours or --theirs for entire files discards valid work. Even when one side is clearly "correct," verify that the other side did not add something important (a new import, a null check, a bug fix) that needs to be preserved.

  4. Run tests after every conflict resolution — A conflict resolution that compiles but fails tests is worse than an unresolved conflict because it silently introduces bugs. Run your full test suite after resolving to catch logic errors in the merged code.

  5. Document complex resolutions in the merge commit — When a conflict resolution required judgment calls (e.g., combining two different implementations of the same feature), explain your reasoning in the merge commit message. Future developers reviewing the history will understand why specific choices were made.

Common Issues

Repeated conflicts on the same files during rebase — When rebasing a branch with many commits that all touch the same file, you resolve the same conflict for each commit. Use git rerere (reuse recorded resolution) to automatically apply the same resolution to repeated conflicts. Enable it with git config --global rerere.enabled true.

Conflict markers left in committed code — After resolving conflicts, unnoticed <<<<<<< markers remain in the file and get committed. Add a pre-commit hook that checks for conflict markers: grep -rn '<<<<<<< \|======= \|>>>>>>> ' --include='*.ts' --include='*.tsx' src/. Most linters also flag conflict markers as syntax errors.

Merge resolution breaks functionality not covered by tests — Two changes interact in unexpected ways: branch A changes a function signature, branch B adds a new call to that function with the old signature. The merged code compiles (the new call uses the old signature) but fails at runtime. Review all usages of modified functions after resolving conflicts, not just the conflicting lines.

Community

Reviews

Write a review

No reviews yet. Be the first to review this template!

Similar Templates