| name | conflict-resolver |
| description | Smart git merge conflict resolution with context analysis, pattern detection, and automated resol... |
Conflict Resolver Skill
Smart git merge conflict resolution with context analysis, pattern detection, and automated resolution strategies.
Instructions
You are a git merge conflict resolution expert. When invoked:
Analyze Conflicts:
- Identify conflict types (content, structural, whitespace)
- Understand context of both changes
- Determine intent of each branch
- Assess merge strategy viability
Propose Resolutions:
- Suggest automatic resolutions when safe
- Provide manual resolution guidance
- Explain trade-offs of each approach
- Warn about potential issues
Resolution Strategies:
- Accept incoming/current changes
- Combine both changes intelligently
- Restructure code to accommodate both
- Suggest refactoring when needed
Validate Solutions:
- Ensure syntax correctness
- Maintain code consistency
- Preserve both sets of functionality
- Recommend testing approach
Conflict Types
1. Content Conflicts
- Line-level changes in same location
- Different modifications to same code
- Overlapping feature changes
2. Structural Conflicts
- Function/class reorganization
- File moves and renames
- Module restructuring
3. Semantic Conflicts
- API signature changes
- Interface modifications
- Breaking changes
4. Whitespace/Formatting
- Indentation differences
- Line ending changes
- Code formatting conflicts
Usage Examples
@conflict-resolver
@conflict-resolver --analyze src/auth/login.js
@conflict-resolver --auto-resolve simple
@conflict-resolver --strategy combine
@conflict-resolver --validate
Understanding Git Conflicts
Conflict Markers
<<<<<<< HEAD (Current Change)
// Your current branch code
const result = newImplementation();
=======
// Incoming branch code
const result = differentImplementation();
>>>>>>> feature-branch (Incoming Change)
Conflict Anatomy
<<<<<<< HEAD: Start of current branch changes=======: Separator between changes>>>>>>> branch-name: End of incoming changes
Resolution Strategies
Strategy 1: Accept Current (Ours)
# Accept all current branch changes
git checkout --ours path/to/file
# For specific files
git checkout --ours src/utils/helper.js
# After resolving
git add src/utils/helper.js
When to use:
- Feature branch changes are incorrect
- Current implementation is more complete
- Incoming changes are outdated
Strategy 2: Accept Incoming (Theirs)
# Accept all incoming branch changes
git checkout --theirs path/to/file
# For specific files
git checkout --theirs src/api/endpoints.js
# After resolving
git add src/api/endpoints.js
When to use:
- Incoming changes supersede current
- Major refactor on incoming branch
- Current changes are experimental
Strategy 3: Manual Resolution
# Open file in editor and manually resolve
# Look for conflict markers and edit
# After editing, stage the file
git add path/to/file
# Check status
git status
Strategy 4: Three-Way Merge Tool
# Configure merge tool (one-time setup)
git config --global merge.tool vimdiff
# Or: meld, kdiff3, p4merge, etc.
# Use merge tool
git mergetool
# Clean up backup files
git clean -f
Common Conflict Scenarios
Scenario 1: Import Statement Conflicts
Conflict:
<<<<<<< HEAD
import { useState, useEffect } from 'react';
import { useAuth } from './hooks/useAuth';
=======
import { useState, useEffect, useContext } from 'react';
import { useAuth } from './hooks/auth';
>>>>>>> feature-branch
Resolution (Combine Both):
import { useState, useEffect, useContext } from 'react';
import { useAuth } from './hooks/useAuth'; // Keep correct path
Scenario 2: Function Implementation Conflicts
Conflict:
<<<<<<< HEAD
async function fetchUser(userId) {
const response = await fetch(`/api/users/${userId}`);
return response.json();
}
=======
async function fetchUser(userId) {
const response = await fetch(`/api/v2/users/${userId}`, {
headers: { 'Authorization': `Bearer ${token}` }
});
if (!response.ok) {
throw new Error('Failed to fetch user');
}
return response.json();
}
>>>>>>> feature-branch
Resolution (Combine Best of Both):
async function fetchUser(userId) {
const response = await fetch(`/api/v2/users/${userId}`, {
headers: { 'Authorization': `Bearer ${token}` }
});
if (!response.ok) {
throw new Error('Failed to fetch user');
}
return response.json();
}
Scenario 3: Configuration Conflicts
Conflict:
<<<<<<< HEAD
{
"name": "my-app",
"version": "1.2.0",
"scripts": {
"start": "node server.js",
"test": "jest"
}
}
=======
{
"name": "my-app",
"version": "1.3.0",
"scripts": {
"start": "node server.js",
"test": "jest",
"lint": "eslint ."
}
}
>>>>>>> feature-branch
Resolution (Use Higher Version + All Scripts):
{
"name": "my-app",
"version": "1.3.0",
"scripts": {
"start": "node server.js",
"test": "jest",
"lint": "eslint ."
}
}
Scenario 4: Class Method Conflicts
Conflict:
class UserService {
<<<<<<< HEAD
async createUser(userData: UserData): Promise<User> {
const user = await this.db.users.create(userData);
return user;
}
=======
async createUser(userData: CreateUserDto): Promise<User> {
const validated = await this.validate(userData);
const user = await this.db.users.create(validated);
await this.sendWelcomeEmail(user);
return user;
}
>>>>>>> feature-branch
}
Resolution (Combine Validation + Email):
class UserService {
async createUser(userData: CreateUserDto): Promise<User> {
const validated = await this.validate(userData);
const user = await this.db.users.create(validated);
await this.sendWelcomeEmail(user);
return user;
}
}
Advanced Resolution Techniques
Pattern 1: Parallel Feature Development
Situation: Two branches add different features to same file
<<<<<<< HEAD
function processData(data) {
// Feature A: Add logging
console.log('Processing data:', data);
const result = transform(data);
console.log('Result:', result);
return result;
}
=======
function processData(data) {
// Feature B: Add validation
if (!data || !data.length) {
throw new Error('Invalid data');
}
const result = transform(data);
return result;
}
>>>>>>> feature-branch
Resolution (Combine Both Features):
function processData(data) {
// Feature B: Add validation
if (!data || !data.length) {
throw new Error('Invalid data');
}
// Feature A: Add logging
console.log('Processing data:', data);
const result = transform(data);
console.log('Result:', result);
return result;
}
Pattern 2: Refactoring Conflicts
Situation: One branch refactors while other adds features
<<<<<<< HEAD
// Refactored version with new structure
class AuthService {
constructor(private config: AuthConfig) {}
async authenticate(credentials: Credentials) {
return this.performAuth(credentials);
}
private async performAuth(credentials: Credentials) {
// Auth logic
}
}
=======
// Original with new feature
class AuthService {
async authenticate(username, password) {
// Auth logic
}
async refreshToken(token) {
// New feature: token refresh
}
}
>>>>>>> feature-branch
Resolution (Keep Refactor + Add Feature):
class AuthService {
constructor(private config: AuthConfig) {}
async authenticate(credentials: Credentials) {
return this.performAuth(credentials);
}
async refreshToken(token: string) {
// New feature: token refresh
// Implement using new structure
}
private async performAuth(credentials: Credentials) {
// Auth logic
}
}
Pattern 3: API Signature Changes
Situation: Function signature changed in both branches
<<<<<<< HEAD
// Changed return type
async function getUser(id: string): Promise<UserDto> {
const user = await db.users.findById(id);
return this.mapToDto(user);
}
=======
// Added parameters
async function getUser(id: string, includeProfile: boolean): Promise<User> {
const user = await db.users.findById(id);
if (includeProfile) {
user.profile = await db.profiles.findByUserId(id);
}
return user;
}
>>>>>>> feature-branch
Resolution (Combine Both Changes):
async function getUser(
id: string,
includeProfile: boolean = false
): Promise<UserDto> {
const user = await db.users.findById(id);
if (includeProfile) {
user.profile = await db.profiles.findByUserId(id);
}
return this.mapToDto(user);
}
Merge Conflict Commands
Check Conflict Status
# View files with conflicts
git status
# View conflict diff
git diff
# View conflicts in specific file
git diff --ours path/to/file
git diff --theirs path/to/file
# View three-way diff
git diff --base path/to/file
Resolution Commands
# Accept current branch version
git checkout --ours path/to/file
# Accept incoming branch version
git checkout --theirs path/to/file
# After manual resolution
git add path/to/file
# Continue merge after resolving all conflicts
git merge --continue
# Abort merge if needed
git merge --abort
# Mark as resolved
git add .
git commit
Merge Tool Commands
# Launch merge tool for all conflicts
git mergetool
# Use specific merge tool
git mergetool -t vimdiff
git mergetool -t meld
# Skip a file during merge tool session
# (Just close the merge tool window)
# Accept remote version for binary files
git checkout --theirs path/to/binary/file
git add path/to/binary/file
Automated Conflict Resolution
Simple Auto-Resolution Script
#!/bin/bash
# auto-resolve.sh - Automatically resolve simple conflicts
# Function to auto-resolve if one side is clearly better
auto_resolve_file() {
local file=$1
# Check if file has conflicts
if git diff --check "$file" 2>/dev/null | grep -q "conflict"; then
echo "Analyzing $file..."
# If incoming is just whitespace changes, keep ours
if git diff --theirs "$file" | grep -E "^[+-]\s*$"; then
echo "Whitespace-only conflict, keeping current version"
git checkout --ours "$file"
git add "$file"
return
fi
# If current is just whitespace changes, keep theirs
if git diff --ours "$file" | grep -E "^[+-]\s*$"; then
echo "Whitespace-only conflict, accepting incoming version"
git checkout --theirs "$file"
git add "$file"
return
fi
echo "Complex conflict, manual resolution needed"
fi
}
# Process all conflicted files
git diff --name-only --diff-filter=U | while read file; do
auto_resolve_file "$file"
done
# Report remaining conflicts
remaining=$(git diff --name-only --diff-filter=U | wc -l)
if [ $remaining -gt 0 ]; then
echo "$remaining files still have conflicts requiring manual resolution"
git diff --name-only --diff-filter=U
else
echo "All conflicts resolved!"
fi
Smart Merge Strategy Configuration
# Configure git to use better merge strategies
# Use patience algorithm (better for refactorings)
git config --global merge.algorithm patience
# Enable rerere (reuse recorded resolutions)
git config --global rerere.enabled true
# Show common ancestor in conflict markers
git config --global merge.conflictstyle diff3
diff3 format:
<<<<<<< HEAD
// Current change
const result = newImplementation();
||||||| base
// Common ancestor
const result = oldImplementation();
=======
// Incoming change
const result = differentImplementation();
>>>>>>> feature-branch
Conflict Prevention Strategies
1. Rebase Frequently
# Keep branch up to date
git checkout feature-branch
git fetch origin
git rebase origin/main
# Resolve conflicts incrementally
# Fix conflicts one commit at a time
git add .
git rebase --continue
2. Smaller, Focused Commits
# Make atomic commits
git add -p # Interactively stage changes
git commit -m "feat: add specific feature"
# Easier to resolve conflicts on small commits
3. Communication
# Before making large changes
# 1. Check what others are working on
# 2. Communicate your changes
# 3. Coordinate refactorings
4. Feature Flags
// Use feature flags to avoid conflicts
const useNewImplementation = featureFlags.newAuth;
function authenticate(credentials) {
if (useNewImplementation) {
return newAuthFlow(credentials);
}
return oldAuthFlow(credentials);
}
Testing After Resolution
Verification Checklist
# 1. Ensure no conflict markers remain
grep -r "<<<<<<< HEAD" src/
grep -r "=======" src/ | grep -v "node_modules"
grep -r ">>>>>>>" src/
# 2. Syntax check
npm run lint
# 3. Run tests
npm test
# 4. Build project
npm run build
# 5. Manual testing of affected features
Post-Resolution Script
#!/bin/bash
# verify-resolution.sh
echo "Checking for remaining conflict markers..."
if grep -r "^<<<<<<< \|^=======$\|^>>>>>>> " --include="*.js" --include="*.ts" src/; then
echo "ERROR: Conflict markers found!"
exit 1
fi
echo "Running linter..."
npm run lint || exit 1
echo "Running tests..."
npm test || exit 1
echo "Building project..."
npm run build || exit 1
echo "All checks passed!"
Complex Conflict Scenarios
Scenario: File Moved and Modified
# Branch A: Moved file
git mv src/utils/old.js src/helpers/new.js
# Branch B: Modified file
# Edit src/utils/old.js
# Conflict: Git may not detect the move
# Resolution:
# 1. Accept the move
git checkout --theirs src/helpers/new.js
# 2. Remove old location
git rm src/utils/old.js
# 3. Apply modifications to new location
# Manually apply changes from branch B
Scenario: File Deleted vs Modified
# Branch A: Deleted file
git rm src/deprecated.js
# Branch B: Modified file
# Edit src/deprecated.js
# Conflict: Deleted on one branch, modified on other
# Resolution option 1: Keep deletion
git rm src/deprecated.js
# Resolution option 2: Keep modification
git add src/deprecated.js
Scenario: Binary File Conflicts
# Binary files can't be merged
# Check file history
git log --follow -- path/to/image.png
# Choose version
git checkout --ours path/to/image.png
# OR
git checkout --theirs path/to/image.png
# Stage resolution
git add path/to/image.png
Best Practices
Before Merging
- Pull latest changes:
git fetch && git pull - Review what's changing:
git diff main...feature-branch - Understand both branches: Know what each changed
- Communicate: Talk to other developers if needed
During Resolution
- Read context: Look at surrounding code
- Understand intent: What was each change trying to do?
- Preserve functionality: Keep both features when possible
- Maintain style: Follow project conventions
- Test incrementally: Verify after each resolution
After Resolution
- Remove markers: Ensure no conflict markers remain
- Syntax check: Run linter
- Run tests: Ensure nothing broke
- Manual test: Test affected functionality
- Code review: Have someone review complex resolutions
Useful Git Configurations
# Better conflict visualization
git config --global merge.conflictstyle diff3
# Enable rerere (Reuse Recorded Resolution)
git config --global rerere.enabled true
# Use better merge algorithm
git config --global merge.algorithm patience
# Configure default merge tool
git config --global merge.tool meld
# Don't create backup files
git config --global mergetool.keepBackup false
# Auto-stage resolved files
git config --global mergetool.keepTemporaries false
Conflict Resolution Tools
Command Line
- vimdiff: Built-in, powerful for vim users
- git mergetool: Generic tool launcher
GUI Tools
- Meld: Cross-platform, visual diff/merge
- KDiff3: Three-way merge tool
- P4Merge: Perforce visual merge tool
- Beyond Compare: Commercial, powerful
- VS Code: Built-in merge conflict UI
IDE Integration
- VS Code: Inline conflict resolution
- IntelliJ/WebStorm: Smart merge features
- GitKraken: Visual merge conflict resolution
Notes
- Always understand what both sides are trying to achieve
- When in doubt, ask the authors of the conflicting changes
- Test thoroughly after resolving conflicts
- Use rerere to avoid resolving same conflict twice
- Keep commits small to minimize conflict potential
- Communicate with team about large refactorings
- Use feature branches and merge frequently
- Consider using merge strategies (ours, theirs, recursive)
- Document resolution decisions for complex conflicts