Managing Merge Conflicts
A comprehensive guide to understanding, resolving, and preventing merge conflicts in Git.
What is a Merge Conflict?
┌─────────────────────────────────────────────────────────────────────────────┐
│ WHAT IS A MERGE CONFLICT? │
└─────────────────────────────────────────────────────────────────────────────┘
A merge conflict occurs when Git cannot automatically combine changes
because TWO PEOPLE modified the SAME LINES in the SAME FILE.
EXAMPLE SCENARIO:
─────────────────
Original file (in develop):
┌────────────────────────────────────┐
│ const taxRate = 0.10; │ ← Line 5
└────────────────────────────────────┘
Developer A (feature/tax-update): Developer B (feature/tax-fix):
┌────────────────────────────────────┐ ┌────────────────────────────────────┐
│ const taxRate = 0.11; │ │ const taxRate = 0.12; │
└────────────────────────────────────┘ └────────────────────────────────────┘
When Developer B tries to merge after Developer A:
┌────────────────────────────────────────────────────────────────────────┐
│ ⚠️ CONFLICT! Git doesn't know which value to use: 0.11 or 0.12? │
└────────────────────────────────────────────────────────────────────────┘
Understanding Conflict Markers
When a conflict occurs, Git marks the conflicting section in your file:
<<<<<<< HEAD
const taxRate = 0.11; // Your current branch changes
=======
const taxRate = 0.12; // Incoming changes from the branch you're merging
>>>>>>> feature/tax-fix
Breakdown:
┌─────────────────────────────────────────────────────────────────────────────┐
│ <<<<<<< HEAD │
│ ───────────────────────────────────────────────────────────────────────── │
│ This marks the START of the conflict │
│ "HEAD" = your current branch (the branch you're ON) │
├─────────────────────────────────────────────────────────────────────────────┤
│ const taxRate = 0.11; │
│ ───────────────────────────────────────────────────────────────────────── │
│ This is YOUR code (current branch) │
├─────────────────────────────────────────────────────────────────────────────┤
│ ======= │
│ ───────────────────────────────────────────────────────────────────────── │
│ This separates the two versions │
├─────────────────────────────────────────────────────────────────────────────┤
│ const taxRate = 0.12; │
│ ───────────────────────────────────────────────────────────────────────── │
│ This is THEIR code (incoming branch) │
├─────────────────────────────────────────────────────────────────────────────┤
│ >>>>>>> feature/tax-fix │
│ ───────────────────────────────────────────────────────────────────────── │
│ This marks the END of the conflict │
│ Shows the name of the incoming branch │
└─────────────────────────────────────────────────────────────────────────────┘
How to Resolve Conflicts (Step-by-Step)
┌─────────────────────────────────────────────────────────────────────────────┐
│ CONFLICT RESOLUTION WORKFLOW │
└─────────────────────────────────────────────────────────────────────────────┘
┌──────────────────┐
│ CONFLICT OCCURS │
│ during merge/ │
│ pull/rebase │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 1. DON'T PANIC! │
│ Run: git status│
│ See conflicting│
│ files │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 2. OPEN file in │
│ VSCode │
│ Look for <<<< │
│ markers │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 3. DECIDE which │
│ code to keep │
│ (or combine) │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 4. EDIT file to │
│ remove markers│
│ keep correct │
│ code │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 5. TEST that the │
│ code works │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 6. STAGE the file│
│ git add <file>│
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 7. COMMIT │
│ git commit │
│ (or continue │
│ merge/rebase) │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ DONE! │
└──────────────────┘
Practical Example: Resolving a Conflict
Scenario: You're merging develop into your feature branch
Step 1: Attempt the merge
git checkout feature/my-feature
git merge develop
# Output:
# Auto-merging src/FileCabinet/SuiteScripts/vendor_invoice.js
# CONFLICT (content): Merge conflict in src/FileCabinet/SuiteScripts/vendor_invoice.js
# Automatic merge failed; fix conflicts and then commit the result.
Step 2: Check which files have conflicts
git status
# Output:
# On branch feature/my-feature
# You have unmerged paths.
#
# Unmerged paths:
# (use "git add <file>..." to mark resolution)
# both modified: src/FileCabinet/SuiteScripts/vendor_invoice.js
Step 3: Open the file in VSCode
VSCode will highlight conflicts with colors:
- Green = Your changes (Current)
- Blue = Incoming changes
You'll see buttons above the conflict:
┌────────────────────────────────────────────────────────────────────────────┐
│ [Accept Current Change] [Accept Incoming Change] [Accept Both] [Compare] │
├────────────────────────────────────────────────────────────────────────────┤
│ <<<<<<< HEAD │
│ const taxRate = 0.11; │
│ const taxName = 'PPN 11%'; │
│ ======= │
│ const taxRate = 0.12; │
│ >>>>>>> develop │
└────────────────────────────────────────────────────────────────────────────┘
Step 4: Choose resolution strategy
Option A: Accept Current Change (keep your version)
const taxRate = 0.11;
const taxName = 'PPN 11%';
Option B: Accept Incoming Change (use their version)
const taxRate = 0.12;
Option C: Accept Both Changes (combine both)
const taxRate = 0.11;
const taxName = 'PPN 11%';
const taxRate = 0.12; // This would cause an error - don't blindly accept both!
Option D: Manual Edit (write custom solution)
// Decided with team: use new tax rate but keep the name
const taxRate = 0.12;
const taxName = 'PPN 12%';
Step 5: Remove ALL conflict markers
Make sure no <<<<<<<, =======, or >>>>>>> remain in the file!
// WRONG - still has markers:
<<<<<<< HEAD
const taxRate = 0.11;
=======
const taxRate = 0.12;
>>>>>>> develop
// CORRECT - clean code:
const taxRate = 0.12;
const taxName = 'PPN 12%';
Step 6: Test the code
# Validate with SDF
Ctrl+Shift+P → SuiteCloud: Validate Project
# Make sure there are no syntax errors
Step 7: Stage and commit
# Stage the resolved file
git add src/FileCabinet/SuiteScripts/vendor_invoice.js
# Complete the merge
git commit -m "Merge develop into feature/my-feature
Resolved conflict in vendor_invoice.js:
- Used new tax rate 0.12 from develop
- Kept taxName variable from feature branch"
Using VSCode Merge Editor (3-Way Merge)
VSCode has a powerful built-in merge editor:
┌─────────────────────────────────────────────────────────────────────────────┐
│ VSCode 3-Way Merge Editor │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ INCOMING (theirs) │ │ CURRENT (yours) │ │
│ │ │ │ │ │
│ │ const taxRate = 0.12│ │ const taxRate = 0.11│ │
│ │ │ │ const taxName = ... │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ RESULT │ │
│ │ │ │
│ │ const taxRate = ??? ← You decide what goes here │ │
│ │ │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ [Accept Incoming] [Accept Current] [Accept Combination] [Complete Merge] │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
To open the Merge Editor:
- Click on a conflicted file in Source Control panel
- Click "Resolve in Merge Editor" button
- Use checkboxes to select which changes to include
- Click "Complete Merge" when done
Conflict Resolution by Scenario
Feature Development Conflicts
When it happens: Merging develop into your feature branch before PR
# Before creating PR, always sync with develop
git checkout feature/my-feature
git fetch origin
git merge origin/develop
# If conflicts occur:
# - Usually in files you both modified
# - Often in shared libraries or configs
Best Practice:
┌─────────────────────────────────────────────────────────────────────────────┐
│ FEATURE BRANCH: Sync with develop FREQUENTLY │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ develop ──●───────●───────●───────●───────●───────●──────► │
│ │ ▲ ▲ ▲ ▲ │ │
│ │ │ │ │ │ │ │
│ feature └───●───┴───●───┴───●───┴───●───┴───●───┘ │
│ │ │ │ │ │ │
│ merge merge merge merge merge │
│ develop develop develop develop (PR) │
│ │
│ ✓ Small, frequent merges = Small, easy conflicts │
│ ✗ One big merge at the end = Big, complex conflicts │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Common Conflict Files in SDF:
| File Type | Why Conflicts Occur | Resolution Tip |
|---|---|---|
manifest.xml | Multiple scripts added | Include all dependencies |
| Custom Records XML | Multiple field additions | Merge all new fields |
| Shared Libraries | Different utility functions | Keep both functions |
| Config files | Different settings | Discuss with team |
Bugfix Conflicts
When it happens: Your bugfix touches code that changed in develop
git checkout bugfix/my-fix
git merge origin/develop
# Conflict likely in:
# - The file you're fixing
# - Related test files
Resolution Strategy:
- Understand both changes - What did develop add? What is your fix?
- Apply your fix to their code - Usually you need to re-apply your fix to the new code
- Test thoroughly - Make sure both the new feature AND your fix work
Example:
// CONFLICT: You fixed a bug, but they refactored the function
// Their version (develop):
function calculateTax(amount, rate) {
// They refactored to use new parameter
return amount * rate;
}
// Your version (bugfix):
function calculateTax(amount) {
// You fixed the null check
if (!amount) return 0;
return amount * TAX_RATE;
}
// RESOLUTION: Apply your fix to their refactored code
function calculateTax(amount, rate) {
if (!amount) return 0; // Your fix
return amount * rate; // Their refactor
}
Hotfix Conflicts
When it happens: Syncing hotfix back to develop
# After merging hotfix to main
git checkout develop
git merge main # Sync the hotfix
# Conflict if develop has diverged significantly
Resolution Strategy:
- Hotfix code takes priority - The fix is critical and tested
- Carefully integrate - Make sure develop's changes don't break the fix
- Test in sandbox - Deploy develop to sandbox and verify fix still works
Preventing Merge Conflicts
┌─────────────────────────────────────────────────────────────────────────────┐
│ CONFLICT PREVENTION BEST PRACTICES │
└─────────────────────────────────────────────────────────────────────────────┘
1. COMMUNICATE WITH YOUR TEAM
─────────────────────────────
"Hey, I'm working on vendor_invoice.js today"
→ Others avoid modifying the same file
2. PULL/MERGE FREQUENTLY
─────────────────────────────
git fetch origin
git merge origin/develop
→ Do this at least daily on long-running branches
3. KEEP BRANCHES SHORT-LIVED
─────────────────────────────
Feature branches: 1-3 days ideal, max 1 week
→ Less time = less divergence = fewer conflicts
4. MAKE SMALL, FOCUSED COMMITS
─────────────────────────────
One change per commit
→ Easier to identify and resolve conflicts
5. AVOID REFORMATTING CODE
─────────────────────────────
Don't change indentation/formatting in files you're not modifying
→ Formatting changes cause unnecessary conflicts
6. USE SEPARATE FILES WHEN POSSIBLE
─────────────────────────────
New functionality? Create a new file instead of adding to existing
→ Different files = no conflicts
Commands Reference
| Command | Description |
|---|---|
git status | See which files have conflicts |
git diff | See the conflict details |
git checkout --ours <file> | Keep your version entirely |
git checkout --theirs <file> | Keep their version entirely |
git add <file> | Mark conflict as resolved |
git merge --abort | Cancel the merge and go back |
git reset --hard HEAD | Abandon all changes (use carefully!) |
When to Ask for Help
- You're not sure which code is correct
- The conflict involves code you don't understand
- Multiple files have complex conflicts
- You've been stuck for more than 15 minutes
- The conflict involves critical business logic
Who to ask:
- The person who wrote the conflicting code (check
git blame) - Your IT Lead
- Senior team member
Troubleshooting Common Issues
"I accidentally committed with conflict markers"
# Fix: Amend the commit
# 1. Fix the file (remove markers)
# 2. Stage the fix
git add <file>
# 3. Amend the commit
git commit --amend
"I want to start over"
# Abort the current merge
git merge --abort
# You're back to before the merge
# Try again when ready
"I accepted the wrong changes"
# If you haven't committed yet:
git checkout --conflict=merge <file>
# This restores the conflict markers so you can try again
# If you already committed:
git revert HEAD
# Then redo the merge
"Too many conflicts, this is overwhelming"
# Option 1: Abort and get help
git merge --abort
# Option 2: Resolve one file at a time
git status # List all conflicted files
# Fix one file
git add <file>
# Repeat for each file
# Finally commit when all resolved
Related Documentation
- Git Workflows - Development workflows with PR and direct merge options
- Commands Reference - Common Git commands
- Troubleshooting - Other Git issues