Git - Conflict Resolution
Advanced
Advanced conflict resolution goes beyond basic merge conflicts, covering sophisticated resolution strategies, automated tools, and complex scenarios that occur in professional development environments.
Understanding Git Conflicts
Conflicts occur when Git cannot automatically merge changes:
# Common conflict scenarios:
# 1. Same line modified differently
# 2. File deleted in one branch, modified in another
# 3. Binary file conflicts
# 4. Rename conflicts
# 5. Submodule conflicts
Conflict Markers Explained
# Standard conflict markers
<<<<<<< HEAD (current branch)
function authenticate(user) {
return validateCredentials(user);
}
=======
function authenticate(user) {
return verifyUserLogin(user);
}
>>>>>>> feature/auth-update (incoming branch)
# Enhanced conflict markers with diff3
git config merge.conflictstyle diff3
<<<<<<< HEAD
function authenticate(user) {
return validateCredentials(user);
}
||||||| merged common ancestors
function authenticate(user) {
return checkUser(user);
}
=======
function authenticate(user) {
return verifyUserLogin(user);
}
>>>>>>> feature/auth-update
Advanced Merge Tools
Configuring Professional Merge Tools
# Configure VS Code as merge tool
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
# Configure Beyond Compare
git config --global merge.tool bc3
git config --global mergetool.bc3.trustExitCode true
# Configure KDiff3
git config --global merge.tool kdiff3
# Configure Vim as merge tool
git config --global merge.tool vimdiff
Custom Merge Tool Configuration
# Configure custom merge tool
git config --global merge.tool custom
git config --global mergetool.custom.cmd 'my-merge-tool "$BASE" "$LOCAL" "$REMOTE" "$MERGED"'
git config --global mergetool.custom.trustExitCode true
# Parameters available:
# $BASE - common ancestor file
# $LOCAL - current branch version
# $REMOTE - branch being merged
# $MERGED - output file
Using Merge Tools Effectively
# Launch merge tool for all conflicts
git mergetool
# Launch merge tool for specific file
git mergetool specific-file.js
# Skip backup files (.orig)
git config --global mergetool.keepBackup false
# Auto-accept merge tool results
git config --global mergetool.trustExitCode true
Conflict Resolution Strategies
Merge Strategy Options
# Prefer our version for conflicts
git merge -X ours feature-branch
# Prefer their version for conflicts
git merge -X theirs feature-branch
# Ignore whitespace differences
git merge -X ignore-space-change feature-branch
git merge -X ignore-all-space feature-branch
# Use patience algorithm (better for large files)
git merge -X patience feature-branch
File-Level Conflict Resolution
# Take entire file from one side
git checkout --ours conflicted-file.js # Use our version
git checkout --theirs conflicted-file.js # Use their version
# After choosing, mark as resolved
git add conflicted-file.js
Selective Conflict Resolution
# Show conflict in patch format
git diff --conflict
# Apply specific conflict resolution interactively
git checkout -p --ours conflicted-file.js
git checkout -p --theirs conflicted-file.js
Complex Conflict Scenarios
Rename Conflicts
# File renamed differently in each branch
# Branch A: oldfile.js → newfile-a.js
# Branch B: oldfile.js → newfile-b.js
git status
# Shows: both deleted: oldfile.js
# added by us: newfile-a.js
# added by them: newfile-b.js
# Resolution options:
# 1. Keep both files
git add newfile-a.js newfile-b.js
# 2. Choose one name, merge content
git mergetool newfile-a.js newfile-b.js
mv newfile-a.js final-name.js
git rm newfile-b.js
git add final-name.js
Delete-Modify Conflicts
# File deleted in one branch, modified in another
git status
# Shows: deleted by us: file.js
# modified by them: file.js
# Keep the file (with their modifications)
git add file.js
# Confirm deletion (ignore their modifications)
git rm file.js
# Merge modifications into new location
git show :3:file.js > new-location/file.js
git add new-location/file.js
git rm file.js
Binary File Conflicts
# Binary files cannot be automatically merged
git status
# Shows: both modified: image.png
# Choose one version
git checkout --ours image.png # Keep our version
git checkout --theirs image.png # Keep their version
# Or manually replace with desired version
cp path/to/desired/image.png image.png
git add image.png
Automated Conflict Resolution
Custom Conflict Resolution Scripts
#!/bin/bash
# auto-resolve-conflicts.sh
# Automatically resolve specific types of conflicts
# Resolve import statement conflicts (keep both)
for file in $(git diff --name-only --diff-filter=U); do
if [[ $file == *.js ]] || [[ $file == *.ts ]]; then
# Extract and merge import statements
python3 merge-imports.py "$file"
git add "$file"
fi
done
Pattern-Based Resolution
#!/bin/bash
# pattern-resolver.sh
# Resolve conflicts based on file patterns
while IFS= read -r file; do
case "$file" in
*.json)
# JSON files: use automatic merge tool
json-merge-tool "$file"
;;
*.md)
# Markdown: prefer union merge
git merge-file --union "$file" "$file" "$file"
;;
*.lock)
# Lock files: regenerate
rm "$file"
npm install # or equivalent
;;
esac
git add "$file"
done < <(git diff --name-only --diff-filter=U)
Advanced Conflict Analysis
Conflict Investigation
# Show detailed conflict information
git ls-files -u # List unmerged files with stages
# Show specific stages of conflicted file
git show :1:file.js # Common ancestor (base)
git show :2:file.js # Our version (current branch)
git show :3:file.js # Their version (incoming branch)
# Compare stages
git diff :2:file.js :3:file.js # Compare our vs their version
Conflict History Analysis
# Find when conflicting lines were introduced
git log -p --follow file.js
# Show commits that touched specific lines
git blame file.js
# Find merge base to understand conflict origin
git merge-base HEAD branch-name
# Show changes since merge base
git diff $(git merge-base HEAD branch-name)..HEAD -- file.js
git diff $(git merge-base HEAD branch-name)..branch-name -- file.js
Team Conflict Resolution Workflows
Conflict Prevention Strategies
# Pre-merge conflict check
#!/bin/bash
# check-conflicts.sh
BRANCH_TO_MERGE=$1
BASE_BRANCH=${2:-main}
# Check for potential conflicts without merging
git merge-tree $(git merge-base $BASE_BRANCH $BRANCH_TO_MERGE) $BASE_BRANCH $BRANCH_TO_MERGE > merge-preview.txt
if grep -q "<<<<<<< " merge-preview.txt; then
echo "Conflicts detected in merge of $BRANCH_TO_MERGE"
echo "Conflicted files:"
grep -B5 -A5 "<<<<<<< " merge-preview.txt
exit 1
else
echo "No conflicts detected"
fi
Collaborative Conflict Resolution
# Team conflict resolution protocol
#!/bin/bash
# team-resolve.sh
BRANCH=$1
echo "Starting collaborative conflict resolution for $BRANCH"
# Create shared branch for conflict resolution
git checkout -b resolve-conflicts-$BRANCH $BRANCH
# Attempt merge
if ! git merge main; then
echo "Conflicts detected. Creating resolution workspace:"
echo "Branch: resolve-conflicts-$BRANCH"
# List conflicted files
echo "Conflicted files:"
git diff --name-only --diff-filter=U
echo "Please resolve conflicts and run:"
echo "git add . && git commit -m 'Resolve merge conflicts'"
echo "git push origin resolve-conflicts-$BRANCH"
fi
Merge Conflict Recovery
Aborting and Retrying Merges
# Abort current merge
git merge --abort
# Reset to pre-merge state
git reset --hard HEAD
# Retry with different strategy
git merge -s recursive -X patience feature-branch
git merge -s resolve feature-branch
Partial Conflict Resolution
# Resolve conflicts file by file
git status # See all conflicted files
# Resolve easy conflicts first
git mergetool easy-file.js
git add easy-file.js
# Leave complex conflicts for later
# Commit partial resolution
git commit --no-edit
# Continue with remaining conflicts
git mergetool complex-file.js
git add complex-file.js
git commit --amend --no-edit
Advanced Merge Tools and Techniques
Three-Way Merge Visualization
# Visual three-way merge with vimdiff
git config --global merge.tool vimdiff3
git mergetool
# Layout in vimdiff3:
# ┌──────────┬──────────┬──────────┐
# │ BASE │ LOCAL │ REMOTE │
# │ (common) │ (ours) │ (theirs) │
# └──────────┴──────────┴──────────┘
# ┌─────────────────────────────────┐
# │ MERGED │
# │ (result) │
# └─────────────────────────────────┘
Semantic Conflict Resolution
# Language-specific merge tools
# For Java: use semantic merge tools
git config merge.java.driver "semantic-merge-java %O %A %B"
# For JSON: use jq-based merger
git config merge.json.driver "jq-merge %O %A %B"
# Apply to specific file types
echo "*.java merge=java" >> .gitattributes
echo "*.json merge=json" >> .gitattributes
Submodule Conflict Resolution
# Submodule conflicts show as:
# both modified: path/to/submodule (commit)
# Check submodule states
git diff path/to/submodule
# Shows:
# -Subproject commit abc1234 (HEAD)
# +Subproject commit def5678 (branch)
# Resolution options:
# 1. Choose specific commit
cd path/to/submodule
git checkout abc1234 # or def5678
cd ..
git add path/to/submodule
# 2. Update to latest
cd path/to/submodule
git pull origin main
cd ..
git add path/to/submodule
Conflict Resolution Testing
# Test conflict resolution
#!/bin/bash
# test-resolution.sh
# Create test scenario
git checkout -b test-conflict-resolution
git merge --no-commit feature-branch
# Simulate conflict resolution
for file in $(git diff --name-only --diff-filter=U); do
echo "Testing resolution for $file"
# Apply resolution
resolve-conflict.sh "$file"
# Verify resolution
if git diff --check; then
echo "✓ No whitespace errors in $file"
else
echo "✗ Whitespace errors in $file"
fi
# Test syntax (for code files)
if [[ $file == *.js ]]; then
node -c "$file" && echo "✓ Valid JavaScript syntax"
fi
done
# Clean up test branch
git reset --hard HEAD
git checkout -
git branch -D test-conflict-resolution
Performance Optimization
Large File Conflict Resolution
# Optimize for large files
git config merge.renameLimit 5000
git config merge.renames true
# Use histogram algorithm for better performance
git merge -X histogram feature-branch
# For very large files, consider external tools
git config merge.large-file.driver "large-file-merger %O %A %B %L"
Parallel Conflict Resolution
#!/bin/bash
# parallel-resolve.sh
# Get list of conflicted files
CONFLICTED_FILES=($(git diff --name-only --diff-filter=U))
# Resolve conflicts in parallel (for independent files)
for file in "${CONFLICTED_FILES[@]}"; do
(
echo "Resolving $file"
auto-resolve-tool "$file"
git add "$file"
) &
done
# Wait for all background jobs
wait
Best Practices
Conflict Resolution Best Practices:
- Understand the context before resolving conflicts
- Test thoroughly after resolution
- Use semantic merge tools for complex file types
- Document resolution decisions for future reference
- Prefer smaller, frequent merges to avoid large conflicts
- Train team members on consistent resolution strategies
Documentation Template
# Conflict Resolution Log Template
## Date: $(date)
## Branch: feature/user-auth → main
## Conflicts Resolved:
### File: src/auth.js
- **Conflict**: Function signature mismatch
- **Resolution**: Combined both approaches, used new signature with backward compatibility
- **Tested**: Unit tests pass, integration tests pass
### File: package.json
- **Conflict**: Dependency version differences
- **Resolution**: Used latest compatible versions
- **Tested**: npm install successful, no breaking changes
## Post-Resolution Checklist:
- [ ] All tests pass
- [ ] Code review completed
- [ ] Documentation updated
- [ ] Performance impact assessed
Troubleshooting
Common Issues
Corrupted Merge State: Sometimes merge state can become corrupted during complex conflict resolution.
# Reset corrupted merge state
rm -rf .git/MERGE_*
git reset --hard HEAD
# Clean up any leftover conflict markers
git clean -fd
# Restart merge process
git merge feature-branch
Recovery Strategies
# Find last successful state
git reflog | head -20
# Reset to known good state
git reset --hard HEAD@{3}
# Alternative: use backup branches
git branch backup-before-merge
git reset --hard backup-before-merge
Key Takeaways
- Tool Mastery: Professional merge tools dramatically improve conflict resolution efficiency
- Strategy Selection: Different conflicts require different resolution approaches
- Automation: Automated resolution handles common patterns consistently
- Team Coordination: Establish clear protocols for collaborative conflict resolution
- Testing: Always verify conflict resolution with comprehensive testing
Advanced conflict resolution skills are essential for professional Git workflows. Master these techniques to handle complex merge scenarios confidently and maintain code quality during integration.