What's Actually Happening

A merge conflict means Git can't automatically combine changes because both branches modified the same part of a file. Git pauses the merge and marks the conflicting sections, waiting for you to decide which changes to keep.

The Error You'll See

bash
$ git merge feature-branch
Auto-merging src/config.js
CONFLICT (content): Merge conflict in src/config.js
Automatic merge failed; fix conflicts and then commit the result.

Or during pull:

bash
$ git pull origin main
CONFLICT (content): Merge conflict in src/app.js
CONFLICT (content): Merge conflict in package.json
Automatic merge failed; fix conflicts and then commit the result.

Understanding Conflict Markers

Open a conflicted file and you'll see:

javascript
// src/config.js
const config = {
<<<<<<< HEAD
  port: 3000,
  debug: true,
=======
  port: 8080,
  production: true,
>>>>>>> feature-branch
};

The markers mean: - <<<<<<< HEAD - Your current branch changes start here - ======= - Divider between your changes and incoming changes - >>>>>>> feature-branch - Incoming branch changes end here

Step 1: Identify All Conflicted Files

bash
git status

Look for "both modified" files:

bash
Unmerged paths:
  (use "git add <file>..." to mark resolution)
	both modified:   src/config.js
	both modified:   package.json

Get a concise list:

bash
git diff --name-only --diff-filter=U

Step 2: Understand Each Conflict

For each conflicted file, examine what changed:

bash
# See detailed conflict view
git diff src/config.js

Or use a visual diff tool:

```bash # VS Code opens merge conflict editor git mergetool --tool=vscode

# Or use default tool git mergetool ```

Step 3: Resolve Conflicts - Choose Your Approach

Option A: Keep Your Changes

javascript
// Remove the markers and keep HEAD version
const config = {
  port: 3000,
  debug: true,
};

Option B: Keep Incoming Changes

javascript
// Remove the markers and keep feature-branch version
const config = {
  port: 8080,
  production: true,
};

Option C: Combine Both Changes

javascript
// Manually merge the changes
const config = {
  port: 8080,
  debug: false,
  production: true,
};

Step 4: Mark Files as Resolved

After fixing each file:

bash
git add src/config.js
git add package.json

Git removes the conflict markers when you add the file.

Step 5: Complete the Merge

Once all conflicts are resolved and added:

bash
git commit

Git creates a merge commit with a default message. Edit if needed:

bash
git commit -m "Merge feature-branch: resolve config port conflict"

Step 6: Quick Resolution Commands

For simple conflicts, use checkout to pick one side:

```bash # Keep your version for a specific file git checkout --ours src/config.js

# Keep incoming version for a specific file git checkout --theirs src/config.js

# Then add to mark resolved git add src/config.js ```

Step 7: Abort If Merge Gets Messy

If conflicts are too complex and you want to start fresh:

bash
git merge --abort

This resets everything to pre-merge state. You can then try a different approach.

Step 8: Use Git Rerere for Repeated Conflicts

If you encounter the same conflict repeatedly:

bash
# Enable rerere (reuse recorded resolution)
git config --global rerere.enabled true

Git remembers how you resolved conflicts and auto-applies the same resolution next time.

Verify the Fix

After completing the merge:

```bash # Check merge completed successfully git status

# Should show clean state # View merge commit git log --oneline -1

# Verify file content cat src/config.js ```

Prevention Tips

  1. 1.Reduce conflicts by:
  2. 2.Small commits - Commit often, merge frequently
  3. 3.Coordinate with team - Don't edit same files simultaneously
  4. 4.Pull before pushing - Keep your branch updated

```bash # Before starting work on shared files git pull origin main

# Regularly rebase your feature branch git fetch origin git rebase origin/main ```