feat: make merge-conflicts more explicit

This commit is contained in:
Bjarke Sporring
2026-01-07 23:03:18 +01:00
parent dff82c847c
commit eb63970b7a
2 changed files with 444 additions and 68 deletions

View File

@@ -1,4 +1,4 @@
# Module 06: Merge Conflicts
# Module 05: Merge Conflicts
## Learning Objectives
@@ -6,101 +6,476 @@ 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
- Resolve merge conflicts manually step-by-step
- Complete a merge after resolving conflicts
## Challenge Description
## Challenge
### Setup
Run the setup script to create your challenge environment:
```powershell
.\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 task is to:
**Your mission:**
1. Attempt to merge the `update-config` branch into `main`
2. Identify and understand the merge conflict
3. Resolve the conflict by keeping both the timeout setting from `main` AND the debug setting from `update-config`
4. Complete the merge with an appropriate commit message
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
## Key Concepts
**Steps to follow:**
### What Are Merge Conflicts?
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
A merge conflict occurs when Git cannot automatically combine changes from two branches because they modify the same part of the same file in different ways. When this happens, Git pauses the merge and asks you to manually resolve the conflict.
## What Are Merge Conflicts?
### Conflict Markers
When a conflict occurs, Git adds special markers to the affected files:
A **merge conflict** occurs when Git cannot automatically combine changes because both branches modified the same lines in the same file.
**Example scenario:**
```
<<<<<<< HEAD
Your current branch's changes
=======
The incoming branch's changes
>>>>>>> branch-name
main branch changes line 5: TIMEOUT = 30
feature branch changes line 5: DEBUG = True
```
- `<<<<<<< HEAD`: Marks the beginning of your current branch's version
- `=======`: Separates the two versions
- `>>>>>>> branch-name`: Marks the end of the incoming branch's version
Git doesn't know which one you want! So it asks you to decide.
### Resolving Conflicts
**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!)
To resolve a conflict:
1. Open the conflicted file in your editor
2. Look for the conflict markers
3. Decide which changes to keep (you can keep one side, the other, or combine both)
4. Remove the conflict markers
5. Stage the resolved file with `git add`
6. Complete the merge with `git commit`
## Step-by-Step: Resolving Your First Conflict
## Useful Commands
### Step 1: Attempt the Merge
```bash
# Merge a branch (may result in conflicts)
git merge <branch-name>
# Check the status during a conflict
git status
# See which files have conflicts
git diff --name-only --diff-filter=U
# View the conflict in detail
git diff
# After resolving, stage the file
git add <file>
# Complete the merge
git commit
# If you want to abort the merge
git merge --abort
# Visualize the branch history
git log --oneline --graph --all
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
```bash
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:
```python
# 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:
```python
<<<<<<< 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)**
```python
# config.py - Application configuration
APP_NAME = "My Application"
VERSION = "1.0.0"
TIMEOUT = 30
```
**Option B: Keep THEIR version (update-config)**
```python
# config.py - Application configuration
APP_NAME = "My Application"
VERSION = "1.0.0"
DEBUG = True
```
**Option C: Keep BOTH (this is what we want!)**
```python
# 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):**
```python
# 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):**
```python
# 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:
```bash
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
```bash
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
```bash
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:**
```bash
git commit -m "Merge update-config: resolve config conflict"
```
---
## Step 9: Verify the Merge
```bash
git log --oneline --graph
```
You should see your merge commit!
```bash
cat config.py
```
Verify the file has BOTH settings and NO conflict markers!
---
## Visual Summary: Before and After
### Before Resolution (WRONG ❌)
```python
# 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 ✅)
```python
# 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
```python
TIMEOUT = 30
======= Still has conflict marker!
DEBUG = True
```
**This is invalid Python code and will crash!**
### ❌ Mistake 2: Committing Without Staging
```bash
# 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
```python
# If the task asks for BOTH settings, this is wrong:
TIMEOUT = 30
# Missing DEBUG = True
```
---
## Useful Commands Reference
```bash
# 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:**
```bash
# 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
```bash
git merge --abort
```
This puts everything back to how it was before the merge. You can try again!
### Option 2: Ask for Help
```bash
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
Run the verification script to check your solution:
Once you've resolved the conflict and completed the merge, verify your solution:
```bash
```powershell
.\verify.ps1
```
The verification will check that:
- The merge conflict was resolved
- The merge was completed successfully
- Both configuration settings were preserved correctly
- The commit history shows the merge
- 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
## Tips
---
- Don't panic when you see a conflict - it's a normal part of working with Git
- Read the conflict markers carefully to understand both versions
- You can use `git status` to see which files have conflicts
- Always test your code after resolving conflicts to ensure it still works
- The conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`) must be completely removed from the final file
## Need to Start Over?
## What You'll Learn
If you want to reset the challenge and start fresh:
Merge conflicts are inevitable when working on a team or even when working alone across multiple branches. Learning to resolve them confidently is an essential Git skill. This module teaches you the fundamentals of conflict resolution that you'll use throughout your development career.
```powershell
.\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!

View File

@@ -128,7 +128,8 @@ if ($parentCount -ne 2) {
}
# Check that both branches are merged
$branches = git branch --merged 2>$null
$branches = git branch --merged update-config 2>$null
Write-Host "$branches $($branches -notmatch 'update-config')"
if ($branches -notmatch "update-config") {
Write-Host "[FAIL] The 'update-config' branch was not merged." -ForegroundColor Red
Set-Location ..