Git Merge Conflict Resolution - Complete Guide
Published: September 25, 2024 | Reading time: 20 minutes
Merge Conflict Overview
Merge conflicts occur when Git cannot automatically merge changes:
Common Conflict Scenarios
# Common Conflict Scenarios
- Same lines modified in different branches
- File deleted in one branch, modified in another
- Binary file conflicts
- Directory structure conflicts
- Merge vs rebase conflicts
- Pull request conflicts
- Cherry-pick conflicts
Understanding Merge Conflicts
Conflict Detection and Analysis
Conflict Detection Commands
# Merge Conflict Detection
# 1. Check for conflicts before merging
git merge --no-commit --no-ff feature-branch
git status
# 2. Identify conflicted files
git status
# Shows files with "both modified" status
# 3. View conflict markers
git diff
# Shows conflict markers: <<<<<<< ======= >>>>>>>
# 4. Check conflict details
git diff --name-only --diff-filter=U
# Lists only conflicted files
# 5. View conflict in specific file
git show :1:filename # Common ancestor
git show :2:filename # Current branch (HEAD)
git show :3:filename # Incoming branch
# 6. Conflict resolution status
git ls-files -u
# Shows unmerged files with stage numbers
# 7. Abort merge if needed
git merge --abort
# Returns to state before merge attempt
# 8. Continue merge after resolution
git add resolved-file
git commit
# Completes the merge
# 9. Check merge result
git log --oneline --graph
# Visual representation of merge history
Manual Conflict Resolution
Step-by-Step Resolution Process
Manual Resolution Steps
# Manual Conflict Resolution Process
# 1. Identify the conflict
git status
# Output shows conflicted files
# 2. Open conflicted file
# Example conflict markers:
<<<<<<< HEAD
function calculateTotal(items) {
return items.reduce((sum, item) => sum + item.price, 0);
}
=======
function calculateTotal(items) {
let total = 0;
for (let item of items) {
total += item.price;
}
return total;
}
>>>>>>> feature-branch
# 3. Understand the conflict
# <<<<<<< HEAD - Current branch changes
# ======= - Separator
# >>>>>>> feature-branch - Incoming branch changes
# 4. Resolve the conflict
# Choose one version or combine both:
function calculateTotal(items) {
// Use reduce for better performance
return items.reduce((sum, item) => sum + item.price, 0);
}
# 5. Remove conflict markers
# Delete all <<<<<<< ======= >>>>>>> lines
# 6. Stage resolved file
git add resolved-file.js
# 7. Complete the merge
git commit -m "Resolve merge conflict in calculateTotal function"
# 8. Verify resolution
git status
# Should show "nothing to commit, working tree clean"
# 9. Test the resolved code
npm test
# Ensure functionality works correctly
# 10. Push merged changes
git push origin main
Conflict Resolution Strategies
Different Resolution Approaches
Resolution Strategies
# Conflict Resolution Strategies
# 1. Accept Current Changes (HEAD)
git checkout --ours filename
git add filename
# 2. Accept Incoming Changes
git checkout --theirs filename
git add filename
# 3. Accept Both Changes
# Manually edit file to include both changes
# Then stage the file
git add filename
# 4. Use Merge Tool
git mergetool
# Opens configured merge tool (vimdiff, kdiff3, etc.)
# 5. Configure Merge Tool
git config --global merge.tool vimdiff
git config --global mergetool.vimdiff.cmd 'vimdiff $LOCAL $REMOTE $MERGED'
# 6. Use VS Code as Merge Tool
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
# 7. Resolve All Conflicts with Strategy
# Accept all current changes
git checkout --ours .
git add .
# Accept all incoming changes
git checkout --theirs .
git add .
# 8. Interactive Resolution
git add -p filename
# Stage specific parts of conflicted file
# 9. Use Merge Driver
# .gitattributes
*.js merge=ours
*.css merge=theirs
# Custom merge driver
git config merge.ours.driver true
git config merge.theirs.driver 'git checkout %O %A'
# 10. Resolve Binary File Conflicts
# Choose one version for binary files
git checkout --ours image.png
git checkout --theirs document.pdf
# 11. Resolve Directory Conflicts
# Remove conflicting directories
git rm -r conflicting-directory
git add new-directory-structure
# 12. Use Rebase Instead of Merge
git rebase main
# Resolve conflicts during rebase
git add resolved-file
git rebase --continue
Advanced Conflict Resolution
Complex Conflict Scenarios
Advanced Resolution Techniques
# Advanced Conflict Resolution
# 1. Resolve Conflicts During Rebase
git rebase main
# Conflicts occur during rebase
# Edit conflicted files
git add resolved-file
git rebase --continue
# Skip problematic commit
git rebase --skip
# Abort rebase
git rebase --abort
# 2. Resolve Conflicts During Cherry-pick
git cherry-pick commit-hash
# Conflicts occur
# Resolve conflicts
git add resolved-file
git cherry-pick --continue
# Abort cherry-pick
git cherry-pick --abort
# 3. Resolve Conflicts During Stash Apply
git stash apply
# Conflicts occur
# Resolve conflicts
git add resolved-file
# Stash apply doesn't auto-commit
# 4. Resolve Conflicts During Pull
git pull origin main
# Conflicts occur
# Resolve conflicts
git add resolved-file
git commit -m "Resolve merge conflicts"
# 5. Resolve Conflicts in Submodules
git submodule update --init --recursive
cd submodule-directory
git checkout main
git pull origin main
cd ..
git add submodule-directory
git commit -m "Update submodule"
# 6. Resolve Conflicts with Large Files
# Use Git LFS for large files
git lfs track "*.psd"
git add .gitattributes
git add file.psd
git commit -m "Add large file with LFS"
# 7. Resolve Conflicts in Configuration Files
# Common config conflicts
git config --global merge.tool vimdiff
git config --global mergetool.keepBackup false
git config --global mergetool.prompt false
# 8. Resolve Conflicts with Line Endings
# Configure line ending handling
git config --global core.autocrlf true # Windows
git config --global core.autocrlf input # Mac/Linux
# .gitattributes for line endings
*.js text eol=lf
*.json text eol=lf
*.md text eol=lf
# 9. Resolve Conflicts with Whitespace
# Ignore whitespace changes
git merge -X ignore-space-change feature-branch
git merge -X ignore-all-space feature-branch
# Configure whitespace handling
git config --global core.whitespace trailing-space,space-before-tab
git config --global apply.whitespace fix
# 10. Resolve Conflicts with File Permissions
# Ignore file mode changes
git config --global core.filemode false
# Check file permissions
git ls-files --stage
# First 3 digits show file mode
# 11. Resolve Conflicts with Symlinks
# Handle symbolic links
git config --global core.symlinks true
# Convert symlinks to regular files
git config --global core.symlinks false
# 12. Resolve Conflicts with Case Sensitivity
# Configure case sensitivity
git config --global core.ignorecase true
# Rename files with case changes
git mv oldfile.js newfile.js
git commit -m "Rename file with case change"
Conflict Prevention
Preventing Merge Conflicts
Conflict Prevention Strategies
# Conflict Prevention Strategies
# 1. Frequent Integration
# Merge main into feature branch regularly
git checkout feature-branch
git merge main
# Resolve conflicts early
# 2. Rebase Instead of Merge
# Keep feature branch up to date
git checkout feature-branch
git rebase main
# Resolve conflicts during rebase
# 3. Small, Focused Commits
# Make small, atomic commits
git add specific-file
git commit -m "Add specific feature"
# 4. Clear Communication
# Coordinate with team members
# Use issue tracking systems
# Document changes
# 5. Use Pull Requests
# Review changes before merging
# Catch conflicts early
# Discuss changes with team
# 6. Branch Protection Rules
# Prevent direct pushes to main
# Require pull requests
# Require status checks
# 7. Automated Testing
# Run tests before merging
# Catch integration issues
# Ensure code quality
# 8. Use Merge Strategies
# Configure merge strategies
git config merge.tool vimdiff
git config mergetool.keepBackup false
# 9. File Organization
# Organize files logically
# Avoid editing same files
# Use clear file structure
# 10. Git Hooks
# Pre-commit hooks
# Pre-push hooks
# Post-merge hooks
# .git/hooks/pre-commit
#!/bin/bash
# Run tests before commit
npm test
if [ $? -ne 0 ]; then
echo "Tests failed. Commit aborted."
exit 1
fi
# .git/hooks/pre-push
#!/bin/bash
# Run integration tests before push
npm run test:integration
if [ $? -ne 0 ]; then
echo "Integration tests failed. Push aborted."
exit 1
fi
# 11. Use Git Attributes
# .gitattributes
*.js text eol=lf
*.json text eol=lf
*.md text eol=lf
*.png binary
*.jpg binary
# 12. Team Workflow
# Establish clear workflow
# Define branch naming
# Set up code review process
# Use continuous integration
# 13. Conflict Resolution Training
# Train team on conflict resolution
# Document resolution process
# Practice conflict scenarios
# Share best practices
# 14. Use Merge Tools
# Configure merge tools
# Use visual diff tools
# Set up merge tool preferences
# Practice with merge tools
# 15. Monitor Conflict Patterns
# Track conflict frequency
# Identify problem areas
# Adjust workflow accordingly
# Improve prevention strategies
Conflict Resolution Tools
Tools and Utilities
Conflict Resolution Tools
# Conflict Resolution Tools
# 1. Built-in Git Tools
# Git mergetool
git mergetool
# Opens configured merge tool
# Git difftool
git difftool
# Opens diff tool for comparison
# 2. Visual Merge Tools
# VS Code
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
# IntelliJ IDEA
git config --global merge.tool intellij
git config --global mergetool.intellij.cmd 'idea merge $LOCAL $REMOTE $MERGED'
# Sublime Merge
git config --global merge.tool smerge
git config --global mergetool.smerge.cmd 'smerge mergetool "$BASE" "$LOCAL" "$REMOTE" -o "$MERGED"'
# 3. Command Line Tools
# Vimdiff
git config --global merge.tool vimdiff
git config --global mergetool.vimdiff.cmd 'vimdiff $LOCAL $REMOTE $MERGED'
# Emacs
git config --global merge.tool emacs
git config --global mergetool.emacs.cmd 'emacs --eval "(ediff-merge-files \"$LOCAL\" \"$REMOTE\" nil \"$MERGED\")"'
# 4. GUI Tools
# KDiff3
git config --global merge.tool kdiff3
git config --global mergetool.kdiff3.cmd 'kdiff3 $LOCAL $REMOTE $MERGED -o $MERGED'
# Meld
git config --global merge.tool meld
git config --global mergetool.meld.cmd 'meld $LOCAL $MERGED $REMOTE'
# Beyond Compare
git config --global merge.tool bc
git config --global mergetool.bc.cmd 'bcomp $LOCAL $REMOTE $MERGED'
# 5. Web-based Tools
# GitHub
# Resolve conflicts directly in GitHub UI
# Use GitHub's conflict resolution interface
# GitLab
# Resolve conflicts in GitLab merge request
# Use GitLab's conflict resolution tools
# 6. Custom Merge Drivers
# .gitattributes
*.js merge=javascript
*.css merge=css
# Custom JavaScript merge driver
git config merge.javascript.name "JavaScript merge driver"
git config merge.javascript.driver "custom-merge-driver %O %A %B %L"
# 7. Conflict Resolution Scripts
#!/bin/bash
# auto-resolve-conflicts.sh
# Function to auto-resolve simple conflicts
auto_resolve_conflicts() {
local file=$1
# Check if file has conflicts
if grep -q "<<<<<<< HEAD" "$file"; then
echo "Resolving conflicts in $file"
# Simple resolution: keep both changes
sed -i '/<<<<<<< HEAD/,/=======/d' "$file"
sed -i 's/>>>>>>> .*//' "$file"
echo "Conflicts resolved in $file"
fi
}
# Process all conflicted files
for file in $(git diff --name-only --diff-filter=U); do
auto_resolve_conflicts "$file"
done
# 8. Conflict Analysis Tools
#!/bin/bash
# analyze-conflicts.sh
# Analyze conflict patterns
analyze_conflicts() {
echo "=== Conflict Analysis ==="
# Count conflicts by file type
echo "Conflicts by file type:"
git diff --name-only --diff-filter=U | sed 's/.*\.//' | sort | uniq -c
# Count conflicts by directory
echo "Conflicts by directory:"
git diff --name-only --diff-filter=U | sed 's/\/.*//' | sort | uniq -c
# Show conflict size
echo "Conflict size:"
git diff --name-only --diff-filter=U | xargs wc -l
}
analyze_conflicts
# 9. Conflict Prevention Tools
#!/bin/bash
# prevent-conflicts.sh
# Check for potential conflicts before merge
check_potential_conflicts() {
local branch=$1
echo "Checking for potential conflicts with $branch"
# Find files modified in both branches
git diff --name-only main..$branch > /tmp/branch_files
git diff --name-only main..HEAD > /tmp/current_files
# Find intersection
comm -12 <(sort /tmp/branch_files) <(sort /tmp/current_files) > /tmp/potential_conflicts
if [ -s /tmp/potential_conflicts ]; then
echo "Potential conflicts in:"
cat /tmp/potential_conflicts
else
echo "No potential conflicts detected"
fi
}
check_potential_conflicts feature-branch
# 10. Conflict Resolution Workflow
#!/bin/bash
# resolve-conflicts-workflow.sh
# Complete conflict resolution workflow
resolve_conflicts_workflow() {
echo "=== Conflict Resolution Workflow ==="
# 1. Check status
echo "1. Checking git status..."
git status
# 2. List conflicted files
echo "2. Conflicted files:"
git diff --name-only --diff-filter=U
# 3. Open merge tool for each file
for file in $(git diff --name-only --diff-filter=U); do
echo "3. Resolving conflicts in $file"
git mergetool "$file"
done
# 4. Verify resolution
echo "4. Verifying resolution..."
git status
# 5. Run tests
echo "5. Running tests..."
npm test
# 6. Commit resolution
echo "6. Committing resolution..."
git commit -m "Resolve merge conflicts"
echo "Conflict resolution complete!"
}
resolve_conflicts_workflow
Best Practices
Conflict Resolution Guidelines
Resolution Best Practices
- Understand the conflict before resolving
- Test resolution thoroughly
- Communicate with team members
- Use appropriate merge tools
- Document resolution decisions
- Prevent conflicts proactively
- Learn from conflict patterns
Common Mistakes
- Rushing through conflict resolution
- Not testing resolved code
- Ignoring conflict markers
- Not communicating with team
- Using wrong resolution strategy
- Not learning from conflicts
- Abandoning merge attempts
Summary
Git merge conflict resolution involves several key components:
- Understanding Conflicts: Detection, analysis, conflict markers
- Resolution Strategies: Manual resolution, merge tools, strategies
- Advanced Techniques: Rebase conflicts, cherry-pick conflicts, complex scenarios
- Prevention: Frequent integration, communication, workflow optimization
- Tools: Merge tools, conflict analysis, automation scripts
- Best Practices: Guidelines, common mistakes, team coordination
Need More Help?
Struggling with Git merge conflicts or need help implementing effective conflict resolution strategies? Our Git experts can help you master conflict resolution.
Get Conflict Resolution Help