feat: add initial module 6

This commit is contained in:
Bjarke Sporring
2026-01-04 17:00:10 +01:00
parent adad27a2e5
commit da23059a69
4 changed files with 375 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
# Module 06: 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
- Complete a merge after resolving conflicts
## Challenge Description
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:
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
## Key Concepts
### What Are Merge Conflicts?
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.
### Conflict Markers
When a conflict occurs, Git adds special markers to the affected files:
```
<<<<<<< HEAD
Your current branch's changes
=======
The incoming branch's changes
>>>>>>> branch-name
```
- `<<<<<<< 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
### Resolving Conflicts
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`
## Useful Commands
```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
```
## Verification
Run the verification script to check your solution:
```bash
.\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
## 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
## What You'll Learn
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.

View File

@@ -0,0 +1,22 @@
#!/usr/bin/env pwsh
<#
.SYNOPSIS
Resets the merge conflicts challenge environment.
.DESCRIPTION
Removes the existing challenge directory and runs setup.ps1
to create a fresh challenge environment.
#>
Write-Host "Resetting challenge environment..." -ForegroundColor Yellow
# Remove existing challenge directory if present
if (Test-Path "challenge") {
Remove-Item -Path "challenge" -Recurse -Force
Write-Host "Removed existing challenge directory." -ForegroundColor Cyan
}
# Run setup script
Write-Host "Running setup script...`n" -ForegroundColor Cyan
& ".\setup.ps1"

View File

@@ -0,0 +1,97 @@
#!/usr/bin/env pwsh
<#
.SYNOPSIS
Sets up the merge conflicts challenge environment.
.DESCRIPTION
Creates a Git repository with a merge conflict scenario involving
a configuration file that has been modified differently on two branches.
#>
# Remove existing challenge directory if present
if (Test-Path "challenge") {
Write-Host "Removing existing challenge directory..." -ForegroundColor Yellow
Remove-Item -Path "challenge" -Recurse -Force
}
# Create challenge directory
Write-Host "Creating challenge environment..." -ForegroundColor Cyan
New-Item -ItemType Directory -Path "challenge" | Out-Null
Set-Location "challenge"
# Initialize git repository
git init | Out-Null
git config user.name "Workshop User" | Out-Null
git config user.email "user@workshop.local" | Out-Null
# Create initial config.json file
$initialConfig = @"
{
"app": {
"name": "MyApp",
"version": "1.0.0",
"port": 3000
}
}
"@
Set-Content -Path "config.json" -Value $initialConfig
git add config.json
git commit -m "Initial configuration" | Out-Null
# Create feature branch
git branch update-config | Out-Null
# On main branch: Add timeout setting
$mainConfig = @"
{
"app": {
"name": "MyApp",
"version": "1.0.0",
"port": 3000,
"timeout": 5000
}
}
"@
Set-Content -Path "config.json" -Value $mainConfig
git add config.json
git commit -m "Add timeout configuration" | Out-Null
# Switch to feature branch: Add debug setting (conflicting change)
git checkout update-config | Out-Null
$featureConfig = @"
{
"app": {
"name": "MyApp",
"version": "1.0.0",
"port": 3000,
"debug": true
}
}
"@
Set-Content -Path "config.json" -Value $featureConfig
git add config.json
git commit -m "Add debug mode configuration" | Out-Null
# Switch back to main branch
git checkout main | Out-Null
# Return to module directory
Set-Location ..
Write-Host "`n========================================" -ForegroundColor Green
Write-Host "Challenge environment created!" -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Green
Write-Host "`nYou are now on the 'main' branch." -ForegroundColor Cyan
Write-Host "There is a branch called 'update-config' with conflicting changes." -ForegroundColor Cyan
Write-Host "`nYour task:" -ForegroundColor Yellow
Write-Host "1. Navigate to the challenge directory: cd challenge" -ForegroundColor White
Write-Host "2. Try to merge the 'update-config' branch into 'main'" -ForegroundColor White
Write-Host "3. Resolve the merge conflict in config.json" -ForegroundColor White
Write-Host "4. Keep BOTH the timeout setting AND the debug setting" -ForegroundColor White
Write-Host "5. Complete the merge" -ForegroundColor White
Write-Host "`nRun '../verify.ps1' from the challenge directory to check your solution.`n" -ForegroundColor Cyan

View File

@@ -0,0 +1,150 @@
#!/usr/bin/env pwsh
<#
.SYNOPSIS
Verifies the merge conflicts challenge solution.
.DESCRIPTION
Checks that the user successfully resolved the merge conflict,
kept both configuration settings, and completed the merge.
#>
Set-Location "challenge" -ErrorAction SilentlyContinue
# Check if challenge directory exists
if (-not (Test-Path "../verify.ps1")) {
Write-Host "Error: Please run this script from the module directory" -ForegroundColor Red
exit 1
}
if (-not (Test-Path ".")) {
Write-Host "Error: Challenge directory not found. Run setup.ps1 first." -ForegroundColor Red
Set-Location ..
exit 1
}
Write-Host "Verifying your solution..." -ForegroundColor Cyan
# Check if git repository exists
if (-not (Test-Path ".git")) {
Write-Host "[FAIL] No git repository found." -ForegroundColor Red
Set-Location ..
exit 1
}
# Check current branch
$currentBranch = git branch --show-current 2>$null
if ($currentBranch -ne "main") {
Write-Host "[FAIL] You should be on the 'main' branch." -ForegroundColor Red
Write-Host "Current branch: $currentBranch" -ForegroundColor Yellow
Write-Host "Hint: Use 'git checkout main' to switch to main branch" -ForegroundColor Yellow
Set-Location ..
exit 1
}
# Check if there's an ongoing merge
if (Test-Path ".git/MERGE_HEAD") {
Write-Host "[FAIL] Merge is not complete. There are still unresolved conflicts." -ForegroundColor Red
Write-Host "Hint: After resolving conflicts in config.json, use:" -ForegroundColor Yellow
Write-Host " git add config.json" -ForegroundColor White
Write-Host " git commit" -ForegroundColor White
Set-Location ..
exit 1
}
# Check if config.json exists
if (-not (Test-Path "config.json")) {
Write-Host "[FAIL] config.json file not found." -ForegroundColor Red
Set-Location ..
exit 1
}
# Read and parse config.json
try {
$configContent = Get-Content "config.json" -Raw
$config = $configContent | ConvertFrom-Json
} catch {
Write-Host "[FAIL] config.json is not valid JSON." -ForegroundColor Red
Write-Host "Make sure you removed all conflict markers (<<<<<<, ======, >>>>>>)" -ForegroundColor Yellow
Set-Location ..
exit 1
}
# Check for conflict markers (in case user forgot to remove them)
if ($configContent -match "<<<<<<|======|>>>>>>") {
Write-Host "[FAIL] Conflict markers still present in config.json" -ForegroundColor Red
Write-Host "Remove all lines containing: <<<<<<, ======, >>>>>>" -ForegroundColor Yellow
Set-Location ..
exit 1
}
# Check if both timeout and debug settings exist
$hasTimeout = $null -ne $config.app.timeout
$hasDebug = $null -ne $config.app.debug
if (-not $hasTimeout) {
Write-Host "[FAIL] The 'timeout' setting is missing from config.json" -ForegroundColor Red
Write-Host "Hint: The resolved file should include both timeout AND debug settings" -ForegroundColor Yellow
Set-Location ..
exit 1
}
if (-not $hasDebug) {
Write-Host "[FAIL] The 'debug' setting is missing from config.json" -ForegroundColor Red
Write-Host "Hint: The resolved file should include both timeout AND debug settings" -ForegroundColor Yellow
Set-Location ..
exit 1
}
# Validate the values
if ($config.app.timeout -ne 5000) {
Write-Host "[FAIL] The 'timeout' value should be 5000" -ForegroundColor Red
Set-Location ..
exit 1
}
if ($config.app.debug -ne $true) {
Write-Host "[FAIL] The 'debug' value should be true" -ForegroundColor Red
Set-Location ..
exit 1
}
# Check that merge commit exists
$commitCount = (git rev-list --count HEAD 2>$null)
if ($commitCount -lt 4) {
Write-Host "[FAIL] Not enough commits. Expected at least 4 commits (including merge commit)." -ForegroundColor Red
Write-Host "Current commits: $commitCount" -ForegroundColor Yellow
Set-Location ..
exit 1
}
# Check that the latest commit is a merge commit (has 2 parents)
$parentCount = (git rev-list --parents -n 1 HEAD 2>$null).Split(' ').Count - 1
if ($parentCount -ne 2) {
Write-Host "[FAIL] The latest commit should be a merge commit." -ForegroundColor Red
Write-Host "Hint: Complete the merge with 'git commit' after resolving conflicts" -ForegroundColor Yellow
Set-Location ..
exit 1
}
# Check that both branches are merged
$branches = git branch --merged 2>$null
if ($branches -notmatch "update-config") {
Write-Host "[FAIL] The 'update-config' branch was not merged." -ForegroundColor Red
Set-Location ..
exit 1
}
# Success!
Write-Host "`n========================================" -ForegroundColor Green
Write-Host "SUCCESS! Challenge completed!" -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Green
Write-Host "`nYou have successfully:" -ForegroundColor Cyan
Write-Host "- Identified the merge conflict" -ForegroundColor White
Write-Host "- Resolved the conflict by keeping both settings" -ForegroundColor White
Write-Host "- Completed the merge with a proper merge commit" -ForegroundColor White
Write-Host "`nYou now understand how to handle merge conflicts!" -ForegroundColor Green
Write-Host "This is a critical skill for collaborative development.`n" -ForegroundColor Green
Set-Location ..
exit 0