Files
2026-01-07 23:03:18 +01:00
..
2026-01-07 17:59:02 +01:00
2026-01-07 22:04:44 +01:00

Module 05: Merge Conflicts

Learning Objectives

By the end of this module, you will:

  • Understand what merge conflicts are and why they occur
  • Identify merge conflicts in your repository
  • Read and interpret conflict markers
  • Resolve merge conflicts manually step-by-step
  • Complete a merge after resolving conflicts

Challenge

Setup

Run the setup script to create your challenge environment:

.\setup.ps1

This will create a challenge/ directory with a repository that has a merge conflict waiting to happen!

Your Task

You have a repository with a main branch and a feature branch called update-config. Both branches have modified the same configuration file in different ways, creating a merge conflict.

Your mission:

  1. Attempt to merge the update-config branch into main
  2. Git will tell you there's a conflict - don't panic!
  3. Resolve the conflict by keeping BOTH settings (timeout AND debug)
  4. Complete the merge

Steps to follow:

  1. Navigate to the challenge directory: cd challenge
  2. Make sure you're on main: git branch
  3. Try to merge: git merge update-config
  4. Git will report a conflict!
  5. Open config.py in your text editor
  6. Follow the step-by-step guide below to resolve it
  7. Save the file, stage it, and commit

What Are Merge Conflicts?

A merge conflict occurs when Git cannot automatically combine changes because both branches modified the same lines in the same file.

Example scenario:

main branch changes line 5:    TIMEOUT = 30
feature branch changes line 5: DEBUG = True

Git doesn't know which one you want! So it asks you to decide.

When do conflicts happen?

  • Two branches modify the same line(s)
  • One branch deletes a file that another branch modifies
  • Different files are changed (no conflict!)
  • Different lines in the same file are changed (no conflict!)

Step-by-Step: Resolving Your First Conflict

Step 1: Attempt the Merge

cd challenge
git merge update-config

You'll see:

Auto-merging config.py
CONFLICT (content): Merge conflict in config.py
Automatic merge failed; fix conflicts and then commit the result.

Don't panic! This is normal. Git is just asking for your help.


Step 2: Check What Happened

git status

You'll see:

On branch main
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   config.py

This tells you that config.py needs your attention!


Step 3: Open the Conflicted File

Open config.py in your text editor. You'll see something like this:

# config.py - Application configuration

APP_NAME = "My Application"
VERSION = "1.0.0"
<<<<<<< HEAD
TIMEOUT = 30
=======
DEBUG = True
>>>>>>> update-config

Let's break down what you're seeing:


Understanding Conflict Markers

Git has added special markers to show you both versions:

<<<<<<< HEAD               Start of YOUR version (current branch)
TIMEOUT = 30               What YOU have on main
=======                    Divider between versions
DEBUG = True               What THEY have on update-config
>>>>>>> update-config      End of THEIR version

The three parts:

  1. <<<<<<< HEAD - Everything between here and ======= is YOUR current branch's version
  2. ======= - This separates the two versions
  3. >>>>>>> update-config - Everything between ======= and here is the INCOMING branch's version

Step 4: Decide What to Keep

You have three options:

Option A: Keep YOUR version (main)

# config.py - Application configuration

APP_NAME = "My Application"
VERSION = "1.0.0"
TIMEOUT = 30

Option B: Keep THEIR version (update-config)

# config.py - Application configuration

APP_NAME = "My Application"
VERSION = "1.0.0"
DEBUG = True

Option C: Keep BOTH (this is what we want!)

# config.py - Application configuration

APP_NAME = "My Application"
VERSION = "1.0.0"
TIMEOUT = 30
DEBUG = True

Step 5: Edit the File to Resolve the Conflict

What the file looks like NOW (with conflict markers):

# config.py - Application configuration

APP_NAME = "My Application"
VERSION = "1.0.0"
<<<<<<< HEAD
TIMEOUT = 30
=======
DEBUG = True
>>>>>>> update-config

What you need to do:

  1. Delete the line <<<<<<< HEAD
  2. Keep the line TIMEOUT = 30
  3. Delete the line =======
  4. Keep the line DEBUG = True
  5. Delete the line >>>>>>> update-config

What the file should look like AFTER (conflict resolved):

# config.py - Application configuration

APP_NAME = "My Application"
VERSION = "1.0.0"
TIMEOUT = 30
DEBUG = True

Save the file!


Step 6: Mark the Conflict as Resolved

Tell Git you've fixed the conflict by staging the file:

git add config.py

This tells Git: "I've resolved the conflict in this file, it's ready to be committed."


Step 7: Check Your Status

git status

You should see:

On branch main
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:
        modified:   config.py

Great! Git knows the conflict is resolved and is ready for you to complete the merge.


Step 8: Complete the Merge

git commit

Git will open your editor with a default merge message:

Merge branch 'update-config'

# Conflicts:
#       config.py

You can keep this message or customize it. Save and close the editor.

Or use a one-liner:

git commit -m "Merge update-config: resolve config conflict"

Step 9: Verify the Merge

git log --oneline --graph

You should see your merge commit!

cat config.py

Verify the file has BOTH settings and NO conflict markers!


Visual Summary: Before and After

Before Resolution (WRONG )

# config.py
APP_NAME = "My Application"
VERSION = "1.0.0"
<<<<<<< HEAD
TIMEOUT = 30
=======
DEBUG = True
>>>>>>> update-config

This will NOT run! Conflict markers are syntax errors!

After Resolution (CORRECT )

# config.py
APP_NAME = "My Application"
VERSION = "1.0.0"
TIMEOUT = 30
DEBUG = True

Clean code, no markers, both settings preserved!


Common Mistakes to Avoid

Mistake 1: Forgetting to Remove Conflict Markers

TIMEOUT = 30
=======   Still has conflict marker!
DEBUG = True

This is invalid Python code and will crash!

Mistake 2: Committing Without Staging

# Wrong order:
git commit         # Error! File not staged

# Correct order:
git add config.py  # Stage first
git commit         # Then commit

Mistake 3: Only Keeping One Side When You Need Both

# If the task asks for BOTH settings, this is wrong:
TIMEOUT = 30
# Missing DEBUG = True

Useful Commands Reference

# During a conflict
git status                    # See which files have conflicts
git diff                      # See the conflict in detail

# Resolving
git add <file>                # Mark file as resolved
git commit                    # Complete the merge

# If you want to start over
git merge --abort             # Cancel the merge, go back to before

# After resolving
git log --oneline --graph     # See the merge commit

Real-World Conflict Resolution Workflow

Here's what you'll do every time you have a conflict:

# 1. Attempt the merge
git merge feature-branch
# → Git says: "CONFLICT! Fix it!"

# 2. Check what's wrong
git status
# → Shows which files have conflicts

# 3. Open the file, find the markers
# <<<<<<< HEAD
# your version
# =======
# their version
# >>>>>>> branch

# 4. Edit the file to resolve
# Remove the markers, keep what you need

# 5. Stage the resolved file
git add config.py

# 6. Complete the merge
git commit -m "Resolve conflict in config.py"

# 7. Celebrate! 🎉

What If You Get Stuck?

Option 1: Abort the Merge

git merge --abort

This puts everything back to how it was before the merge. You can try again!

Option 2: Ask for Help

git status           # See what's going on
git diff             # See the conflict details

Pro Tips

Use git status constantly - It tells you exactly what to do next

Search for <<<<<<< - Your editor's search function can find all conflicts quickly

Test after resolving - Make sure your code still works!

Read both sides carefully - Sometimes you need parts from each version

Take your time - Conflicts are not a race. Understand what changed and why.


Verification

Once you've resolved the conflict and completed the merge, verify your solution:

.\verify.ps1

The verification will check that:

  • The merge conflict was resolved
  • The merge was completed successfully
  • BOTH settings are in the config file (TIMEOUT and DEBUG)
  • NO conflict markers remain
  • The merge commit exists in history

Need to Start Over?

If you want to reset the challenge and start fresh:

.\reset.ps1

What You've Learned

🎉 Congratulations! You can now:

  • Recognize when a merge conflict occurs
  • Read and understand conflict markers
  • Edit files to resolve conflicts
  • Stage resolved files with git add
  • Complete a merge with git commit

This is a critical skill! Every developer encounters merge conflicts. Now you know exactly what to do when they happen.


Quick Reference Card

When you see a conflict:

  1. Don't panic
  2. Run git status to see which files
  3. Open the file in your editor
  4. Find the markers (<<<<<<<, =======, >>>>>>>)
  5. Decide what to keep (one side, other side, or both)
  6. Remove ALL markers (the <<<<<<<, =======, >>>>>>> lines)
  7. Save the file
  8. Stage it (git add filename)
  9. Commit (git commit)
  10. Verify (git status, git log --oneline --graph)

Remember: The conflict markers are NOT valid code - they MUST be removed!