feat: add initial module 6
This commit is contained in:
106
module-06-merge-conflicts/README.md
Normal file
106
module-06-merge-conflicts/README.md
Normal 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.
|
||||
22
module-06-merge-conflicts/reset.ps1
Normal file
22
module-06-merge-conflicts/reset.ps1
Normal 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"
|
||||
97
module-06-merge-conflicts/setup.ps1
Normal file
97
module-06-merge-conflicts/setup.ps1
Normal 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
|
||||
150
module-06-merge-conflicts/verify.ps1
Normal file
150
module-06-merge-conflicts/verify.ps1
Normal 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
|
||||
Reference in New Issue
Block a user