refactor: we're breaking out merge-conflicts
This commit is contained in:
File diff suppressed because it is too large
Load Diff
1
01-essentials/03-branching-and-merging/challenge
Submodule
1
01-essentials/03-branching-and-merging/challenge
Submodule
Submodule 01-essentials/03-branching-and-merging/challenge added at 8ae52cc25c
@@ -1,216 +1,23 @@
|
||||
#!/usr/bin/env pwsh
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Resets the challenge environment to a specific checkpoint.
|
||||
Resets the Module 03 challenge environment.
|
||||
|
||||
.DESCRIPTION
|
||||
This script allows you to jump to any checkpoint in the module,
|
||||
resetting your repository to that state. Useful for skipping ahead,
|
||||
starting over, or practicing specific sections.
|
||||
|
||||
.PARAMETER Checkpoint
|
||||
The checkpoint to reset to: start, merge, or merge-conflict.
|
||||
If not specified, displays help information.
|
||||
|
||||
.EXAMPLE
|
||||
.\reset.ps1
|
||||
Shows available checkpoints and current status.
|
||||
|
||||
.EXAMPLE
|
||||
.\reset.ps1 start
|
||||
Resets to the beginning (branching basics section).
|
||||
|
||||
.EXAMPLE
|
||||
.\reset.ps1 merge
|
||||
Jumps to the merging section (feature-login branch already exists).
|
||||
|
||||
.EXAMPLE
|
||||
.\reset.ps1 merge-conflict
|
||||
Jumps to the conflict resolution section (merge already complete).
|
||||
This script removes the challenge directory, allowing you to start fresh.
|
||||
Run setup.ps1 again after resetting to recreate the environment.
|
||||
#>
|
||||
|
||||
param(
|
||||
[ValidateSet('start', 'merge', 'merge-conflict', '')]
|
||||
[string]$Checkpoint = ''
|
||||
)
|
||||
Write-Host "`n=== Resetting Module 03 Challenge ===" -ForegroundColor Cyan
|
||||
|
||||
# Checkpoint to tag mapping
|
||||
$checkpointTags = @{
|
||||
'start' = 'checkpoint-start'
|
||||
'merge' = 'checkpoint-merge'
|
||||
'merge-conflict' = 'checkpoint-merge-conflict'
|
||||
if (Test-Path "challenge") {
|
||||
Write-Host "Removing challenge directory..." -ForegroundColor Yellow
|
||||
Remove-Item -Recurse -Force "challenge"
|
||||
Write-Host "`n[SUCCESS] Challenge environment reset complete!" -ForegroundColor Green
|
||||
Write-Host "`nRun .\setup.ps1 to create a fresh challenge environment." -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
} else {
|
||||
Write-Host "`n[INFO] No challenge directory found. Nothing to reset." -ForegroundColor Yellow
|
||||
Write-Host "Run .\setup.ps1 to create the challenge environment." -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
# Checkpoint descriptions
|
||||
$checkpointDescriptions = @{
|
||||
'start' = 'Branching Basics - Create and work with feature branches'
|
||||
'merge' = 'Merging Branches - Merge feature-login into main'
|
||||
'merge-conflict' = 'Resolving Conflicts - Fix merge conflicts in config.json'
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Display help if no checkpoint specified
|
||||
# ============================================================================
|
||||
if ($Checkpoint -eq '') {
|
||||
Write-Host "`n=== Module 03: Branching and Merging - Checkpoints ===" -ForegroundColor Cyan
|
||||
Write-Host "`nAvailable checkpoints:" -ForegroundColor White
|
||||
Write-Host ""
|
||||
|
||||
foreach ($key in @('start', 'merge', 'merge-conflict')) {
|
||||
$desc = $checkpointDescriptions[$key]
|
||||
Write-Host " $key" -ForegroundColor Green -NoNewline
|
||||
Write-Host " - $desc" -ForegroundColor White
|
||||
}
|
||||
|
||||
Write-Host "`nUsage:" -ForegroundColor Cyan
|
||||
Write-Host " .\reset.ps1 <checkpoint>" -ForegroundColor White
|
||||
Write-Host ""
|
||||
Write-Host "Examples:" -ForegroundColor Cyan
|
||||
Write-Host " .\reset.ps1 start # Start from the beginning" -ForegroundColor White
|
||||
Write-Host " .\reset.ps1 merge # Jump to merging section" -ForegroundColor White
|
||||
Write-Host " .\reset.ps1 merge-conflict # Jump to conflict resolution" -ForegroundColor White
|
||||
Write-Host ""
|
||||
|
||||
# Try to detect current checkpoint
|
||||
if (Test-Path "challenge/.git") {
|
||||
Push-Location "challenge"
|
||||
$currentBranch = git branch --show-current 2>$null
|
||||
$currentCommit = git rev-parse HEAD 2>$null
|
||||
|
||||
# Check which checkpoint we're at
|
||||
$currentCheckpoint = $null
|
||||
foreach ($cp in @('start', 'merge', 'merge-conflict')) {
|
||||
$tagCommit = git rev-parse $checkpointTags[$cp] 2>$null
|
||||
if ($currentCommit -eq $tagCommit) {
|
||||
$currentCheckpoint = $cp
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if ($currentCheckpoint) {
|
||||
Write-Host "Current checkpoint: " -ForegroundColor Yellow -NoNewline
|
||||
Write-Host "$currentCheckpoint" -ForegroundColor Green -NoNewline
|
||||
Write-Host " (on branch $currentBranch)" -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Host "Current status: " -ForegroundColor Yellow -NoNewline
|
||||
Write-Host "In progress (on branch $currentBranch)" -ForegroundColor White
|
||||
}
|
||||
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
exit 0
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Validate challenge directory exists
|
||||
# ============================================================================
|
||||
if (-not (Test-Path "challenge")) {
|
||||
Write-Host "[ERROR] Challenge directory not found." -ForegroundColor Red
|
||||
Write-Host "Run .\setup.ps1 first to create the challenge environment." -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
|
||||
if (-not (Test-Path "challenge/.git")) {
|
||||
Write-Host "[ERROR] No git repository found in challenge directory." -ForegroundColor Red
|
||||
Write-Host "Run .\setup.ps1 first to create the challenge environment." -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Navigate to challenge directory
|
||||
Push-Location "challenge"
|
||||
|
||||
# ============================================================================
|
||||
# Verify the checkpoint tag exists
|
||||
# ============================================================================
|
||||
$targetTag = $checkpointTags[$Checkpoint]
|
||||
$tagExists = git tag -l $targetTag
|
||||
|
||||
if (-not $tagExists) {
|
||||
Write-Host "[ERROR] Checkpoint tag '$targetTag' not found." -ForegroundColor Red
|
||||
Write-Host "Run ..\setup.ps1 to recreate the challenge environment." -ForegroundColor Yellow
|
||||
Pop-Location
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Check for uncommitted changes
|
||||
# ============================================================================
|
||||
$statusOutput = git status --porcelain 2>$null
|
||||
|
||||
if ($statusOutput) {
|
||||
Write-Host "`n[WARNING] You have uncommitted changes!" -ForegroundColor Yellow
|
||||
Write-Host "The following changes will be lost:" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
git status --short
|
||||
Write-Host ""
|
||||
|
||||
$response = Read-Host "Continue and discard all changes? (y/N)"
|
||||
if ($response -ne 'y' -and $response -ne 'Y') {
|
||||
Write-Host "`nReset cancelled." -ForegroundColor Cyan
|
||||
Pop-Location
|
||||
exit 0
|
||||
}
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Reset to checkpoint
|
||||
# ============================================================================
|
||||
Write-Host "`nResetting to checkpoint: $Checkpoint" -ForegroundColor Cyan
|
||||
Write-Host "Description: $($checkpointDescriptions[$Checkpoint])" -ForegroundColor White
|
||||
Write-Host ""
|
||||
|
||||
try {
|
||||
# Reset to the checkpoint tag
|
||||
git reset --hard $targetTag 2>&1 | Out-Null
|
||||
|
||||
# Clean untracked files
|
||||
git clean -fd 2>&1 | Out-Null
|
||||
|
||||
# Ensure we're on main branch
|
||||
$currentBranch = git branch --show-current
|
||||
if ($currentBranch -ne 'main') {
|
||||
git switch main 2>&1 | Out-Null
|
||||
git reset --hard $targetTag 2>&1 | Out-Null
|
||||
}
|
||||
|
||||
Write-Host "[SUCCESS] Reset to checkpoint '$Checkpoint' complete!" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
# Show what to do next
|
||||
switch ($Checkpoint) {
|
||||
'start' {
|
||||
Write-Host "Next steps:" -ForegroundColor Cyan
|
||||
Write-Host " 1. Create a new branch: git switch -c feature-login" -ForegroundColor White
|
||||
Write-Host " 2. Create login.py and make 2+ commits" -ForegroundColor White
|
||||
Write-Host " 3. Verify: ..\verify.ps1 start" -ForegroundColor White
|
||||
}
|
||||
'merge' {
|
||||
Write-Host "Next steps:" -ForegroundColor Cyan
|
||||
Write-Host " 1. View branch structure: git log --oneline --graph --all" -ForegroundColor White
|
||||
Write-Host " 2. Merge feature-login: git merge feature-login" -ForegroundColor White
|
||||
Write-Host " 3. Verify: ..\verify.ps1 merge" -ForegroundColor White
|
||||
}
|
||||
'merge-conflict' {
|
||||
Write-Host "Next steps:" -ForegroundColor Cyan
|
||||
Write-Host " 1. Attempt merge: git merge update-config" -ForegroundColor White
|
||||
Write-Host " 2. Resolve conflicts in config.json" -ForegroundColor White
|
||||
Write-Host " 3. Complete merge: git add config.json && git commit" -ForegroundColor White
|
||||
Write-Host " 4. Verify: ..\verify.ps1 merge-conflict" -ForegroundColor White
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "View current state: git log --oneline --graph --all" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
} catch {
|
||||
Write-Host "[ERROR] Failed to reset to checkpoint." -ForegroundColor Red
|
||||
Write-Host $_.Exception.Message -ForegroundColor Red
|
||||
Pop-Location
|
||||
exit 1
|
||||
}
|
||||
|
||||
Pop-Location
|
||||
exit 0
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
#!/usr/bin/env pwsh
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Sets up the Module 03 checkpoint-based challenge environment.
|
||||
Sets up the Module 03 challenge environment for branching and merging.
|
||||
|
||||
.DESCRIPTION
|
||||
This script creates a challenge directory with a complete Git repository
|
||||
containing all commits and checkpoints for learning branching, merging,
|
||||
and merge conflict resolution in one continuous workflow.
|
||||
|
||||
The script creates three checkpoints:
|
||||
- checkpoint-start: Beginning of branching basics
|
||||
- checkpoint-merge: Beginning of merging section
|
||||
- checkpoint-merge-conflict: Beginning of conflict resolution
|
||||
This script creates a challenge directory with a Git repository containing
|
||||
a realistic project history with multiple merged branches. Students will see
|
||||
what branching and merging looks like in practice, then create their own
|
||||
branches to experiment.
|
||||
#>
|
||||
|
||||
Write-Host "`n=== Setting up Module 03: Branching and Merging ===" -ForegroundColor Cyan
|
||||
@@ -36,113 +32,75 @@ git config user.name "Workshop Student"
|
||||
git config user.email "student@example.com"
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 1: Branching Basics - Initial commits on main
|
||||
# Create a realistic project history with multiple merged branches
|
||||
# ============================================================================
|
||||
Write-Host "`nPhase 1: Creating initial project structure..." -ForegroundColor Cyan
|
||||
Write-Host "Creating project history with multiple branches..." -ForegroundColor Cyan
|
||||
|
||||
# Commit 1: Initial commit
|
||||
$mainContent = @"
|
||||
# main.py - Main application file
|
||||
# Initial commits on main
|
||||
$readmeContent = @"
|
||||
# My Application
|
||||
|
||||
def main():
|
||||
print("Welcome to the Application!")
|
||||
print("This is the main branch")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
A sample application for learning Git branching and merging.
|
||||
"@
|
||||
Set-Content -Path "main.py" -Value $mainContent
|
||||
Set-Content -Path "README.md" -Value $readmeContent
|
||||
git add .
|
||||
git commit -m "Initial commit" | Out-Null
|
||||
|
||||
# Commit 2: Add main functionality
|
||||
$mainContent = @"
|
||||
# main.py - Main application file
|
||||
|
||||
def main():
|
||||
print("Welcome to the Application!")
|
||||
print("This is the main branch")
|
||||
run_application()
|
||||
|
||||
def run_application():
|
||||
print("Application is running...")
|
||||
print("Ready for new features!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
"@
|
||||
Set-Content -Path "main.py" -Value $mainContent
|
||||
git add .
|
||||
git commit -m "Add main functionality" | Out-Null
|
||||
|
||||
# Tag checkpoint-start (students begin here - will create feature-login)
|
||||
Write-Host "Creating checkpoint: start" -ForegroundColor Green
|
||||
git tag checkpoint-start
|
||||
git commit -m "Add main application file" | Out-Null
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 2: Create feature-login branch (what students will do in checkpoint 1)
|
||||
# Branch 1: feature-login (will be merged)
|
||||
# ============================================================================
|
||||
Write-Host "Phase 2: Creating feature-login branch..." -ForegroundColor Cyan
|
||||
|
||||
# Create and switch to feature-login branch
|
||||
Write-Host "Creating feature-login branch..." -ForegroundColor Cyan
|
||||
git switch -c feature-login | Out-Null
|
||||
|
||||
# Commit 3: Add login module
|
||||
$loginContent = @"
|
||||
# login.py - User login module
|
||||
# login.py - User authentication
|
||||
|
||||
def login(username, password):
|
||||
"""Authenticate a user."""
|
||||
print(f"Authenticating user: {username}")
|
||||
# TODO: Add actual authentication logic
|
||||
return True
|
||||
|
||||
def logout(username):
|
||||
"""Log out a user."""
|
||||
print(f"Logging out user: {username}")
|
||||
print(f"Logging in user: {username}")
|
||||
return True
|
||||
"@
|
||||
Set-Content -Path "login.py" -Value $loginContent
|
||||
git add .
|
||||
git commit -m "Add login module" | Out-Null
|
||||
|
||||
# Commit 4: Add password validation
|
||||
$loginContent = @"
|
||||
# login.py - User login module
|
||||
# login.py - User authentication
|
||||
|
||||
def validate_password(password):
|
||||
"""Validate password strength."""
|
||||
if len(password) < 8:
|
||||
return False
|
||||
return True
|
||||
return len(password) >= 8
|
||||
|
||||
def login(username, password):
|
||||
"""Authenticate a user."""
|
||||
if not validate_password(password):
|
||||
print("Password too weak!")
|
||||
return False
|
||||
print(f"Authenticating user: {username}")
|
||||
# TODO: Add actual authentication logic
|
||||
return True
|
||||
|
||||
def logout(username):
|
||||
"""Log out a user."""
|
||||
print(f"Logging out user: {username}")
|
||||
print(f"Logging in user: {username}")
|
||||
return True
|
||||
"@
|
||||
Set-Content -Path "login.py" -Value $loginContent
|
||||
git add .
|
||||
git commit -m "Add password validation" | Out-Null
|
||||
|
||||
# Switch back to main
|
||||
# Switch back to main and make more commits
|
||||
git switch main | Out-Null
|
||||
|
||||
# Now create divergence - add commits to main while feature-login exists
|
||||
Write-Host "Creating divergent history on main..." -ForegroundColor Cyan
|
||||
|
||||
# Commit 5: Add app.py with basic functionality
|
||||
$appContent = @"
|
||||
# app.py - Main application entry point
|
||||
# app.py - Application entry point
|
||||
|
||||
from main import main
|
||||
|
||||
@@ -150,7 +108,6 @@ def run():
|
||||
"""Run the application."""
|
||||
print("Starting application...")
|
||||
main()
|
||||
print("Application finished.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
@@ -159,16 +116,65 @@ Set-Content -Path "app.py" -Value $appContent
|
||||
git add .
|
||||
git commit -m "Add app.py entry point" | Out-Null
|
||||
|
||||
# Commit 6: Add README
|
||||
# Merge feature-login into main
|
||||
Write-Host "Merging feature-login into main..." -ForegroundColor Green
|
||||
git merge feature-login --no-edit | Out-Null
|
||||
|
||||
# ============================================================================
|
||||
# Branch 2: feature-api (will be merged)
|
||||
# ============================================================================
|
||||
Write-Host "Creating feature-api branch..." -ForegroundColor Cyan
|
||||
git switch -c feature-api | Out-Null
|
||||
|
||||
$apiContent = @"
|
||||
# api.py - API endpoints
|
||||
|
||||
def get_data():
|
||||
"""Retrieve data from API."""
|
||||
return {"status": "ok", "data": []}
|
||||
|
||||
def post_data(data):
|
||||
"""Send data to API."""
|
||||
print(f"Posting data: {data}")
|
||||
return {"status": "ok"}
|
||||
"@
|
||||
Set-Content -Path "api.py" -Value $apiContent
|
||||
git add .
|
||||
git commit -m "Add API module" | Out-Null
|
||||
|
||||
$apiContent = @"
|
||||
# api.py - API endpoints
|
||||
|
||||
def get_data():
|
||||
"""Retrieve data from API."""
|
||||
return {"status": "ok", "data": []}
|
||||
|
||||
def post_data(data):
|
||||
"""Send data to API."""
|
||||
print(f"Posting data: {data}")
|
||||
return {"status": "ok"}
|
||||
|
||||
def delete_data(id):
|
||||
"""Delete data by ID."""
|
||||
print(f"Deleting data: {id}")
|
||||
return {"status": "ok"}
|
||||
"@
|
||||
Set-Content -Path "api.py" -Value $apiContent
|
||||
git add .
|
||||
git commit -m "Add delete endpoint to API" | Out-Null
|
||||
|
||||
# Switch back to main and add documentation
|
||||
git switch main | Out-Null
|
||||
|
||||
$readmeContent = @"
|
||||
# My Application
|
||||
|
||||
Welcome to my application!
|
||||
A sample application for learning Git branching and merging.
|
||||
|
||||
## Features
|
||||
|
||||
- Main functionality
|
||||
- More features coming soon
|
||||
- User authentication
|
||||
- Main application logic
|
||||
|
||||
## Setup
|
||||
|
||||
@@ -176,104 +182,107 @@ Run: python app.py
|
||||
"@
|
||||
Set-Content -Path "README.md" -Value $readmeContent
|
||||
git add .
|
||||
git commit -m "Add README documentation" | Out-Null
|
||||
git commit -m "Update README with setup instructions" | Out-Null
|
||||
|
||||
# Tag checkpoint-merge (students begin merging here - divergent branches ready)
|
||||
Write-Host "Creating checkpoint: merge" -ForegroundColor Green
|
||||
git tag checkpoint-merge
|
||||
# Merge feature-api into main
|
||||
Write-Host "Merging feature-api into main..." -ForegroundColor Green
|
||||
git merge feature-api --no-edit | Out-Null
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 3: Merge feature-login into main (what students will do in checkpoint 2)
|
||||
# Branch 3: feature-database (will be merged)
|
||||
# ============================================================================
|
||||
Write-Host "Phase 3: Merging feature-login into main..." -ForegroundColor Cyan
|
||||
Write-Host "Creating feature-database branch..." -ForegroundColor Cyan
|
||||
git switch -c feature-database | Out-Null
|
||||
|
||||
# Merge feature-login into main (will create three-way merge commit)
|
||||
git merge feature-login --no-edit | Out-Null
|
||||
$dbContent = @"
|
||||
# database.py - Database operations
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 4: Create conflict scenario (what students will do in checkpoint 3)
|
||||
# ============================================================================
|
||||
Write-Host "Phase 4: Creating merge conflict scenario..." -ForegroundColor Cyan
|
||||
class Database:
|
||||
def __init__(self):
|
||||
self.connection = None
|
||||
|
||||
# Create config.json file on main
|
||||
$initialConfig = @"
|
||||
{
|
||||
"app": {
|
||||
"name": "MyApp",
|
||||
"version": "1.0.0",
|
||||
"port": 3000
|
||||
}
|
||||
}
|
||||
def connect(self):
|
||||
"""Connect to database."""
|
||||
print("Connecting to database...")
|
||||
self.connection = True
|
||||
|
||||
def query(self, sql):
|
||||
"""Execute SQL query."""
|
||||
print(f"Executing: {sql}")
|
||||
return []
|
||||
"@
|
||||
Set-Content -Path "config.json" -Value $initialConfig
|
||||
git add config.json
|
||||
git commit -m "Add initial configuration" | Out-Null
|
||||
Set-Content -Path "database.py" -Value $dbContent
|
||||
git add .
|
||||
git commit -m "Add database module" | Out-Null
|
||||
|
||||
# On main branch: Add timeout setting
|
||||
$mainConfig = @"
|
||||
{
|
||||
"app": {
|
||||
"name": "MyApp",
|
||||
"version": "1.0.0",
|
||||
"port": 3000,
|
||||
"timeout": 5000
|
||||
}
|
||||
}
|
||||
$dbContent = @"
|
||||
# database.py - Database operations
|
||||
|
||||
class Database:
|
||||
def __init__(self):
|
||||
self.connection = None
|
||||
|
||||
def connect(self):
|
||||
"""Connect to database."""
|
||||
print("Connecting to database...")
|
||||
self.connection = True
|
||||
|
||||
def disconnect(self):
|
||||
"""Disconnect from database."""
|
||||
print("Disconnecting from database...")
|
||||
self.connection = None
|
||||
|
||||
def query(self, sql):
|
||||
"""Execute SQL query."""
|
||||
print(f"Executing: {sql}")
|
||||
return []
|
||||
"@
|
||||
Set-Content -Path "config.json" -Value $mainConfig
|
||||
git add config.json
|
||||
git commit -m "Add timeout configuration" | Out-Null
|
||||
Set-Content -Path "database.py" -Value $dbContent
|
||||
git add .
|
||||
git commit -m "Add disconnect method" | Out-Null
|
||||
|
||||
# Create update-config branch from the commit before timeout was added
|
||||
git switch -c update-config HEAD~1 | Out-Null
|
||||
|
||||
# On update-config branch: Add debug setting (conflicting change)
|
||||
$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
|
||||
# Switch to main and merge
|
||||
git switch main | Out-Null
|
||||
Write-Host "Merging feature-database into main..." -ForegroundColor Green
|
||||
git merge feature-database --no-edit | Out-Null
|
||||
|
||||
# Tag checkpoint-merge-conflict (students begin conflict resolution here - on main with timeout, update-config has debug)
|
||||
Write-Host "Creating checkpoint: merge-conflict" -ForegroundColor Green
|
||||
git tag checkpoint-merge-conflict
|
||||
# Final update on main
|
||||
$readmeContent = @"
|
||||
# My Application
|
||||
|
||||
# ============================================================================
|
||||
# Reset to checkpoint-start so students begin at the beginning
|
||||
# ============================================================================
|
||||
Write-Host "`nResetting to checkpoint-start..." -ForegroundColor Yellow
|
||||
git reset --hard checkpoint-start | Out-Null
|
||||
git clean -fd | Out-Null
|
||||
A sample application for learning Git branching and merging.
|
||||
|
||||
## Features
|
||||
|
||||
- User authentication
|
||||
- API endpoints
|
||||
- Database operations
|
||||
- Main application logic
|
||||
|
||||
## Setup
|
||||
|
||||
Run: python app.py
|
||||
|
||||
## Requirements
|
||||
|
||||
- Python 3.6+
|
||||
"@
|
||||
Set-Content -Path "README.md" -Value $readmeContent
|
||||
git add .
|
||||
git commit -m "Update README with all features" | Out-Null
|
||||
|
||||
# Return to module directory
|
||||
Set-Location ..
|
||||
|
||||
Write-Host "`n=== Setup Complete! ===" -ForegroundColor Green
|
||||
Write-Host "`nYour challenge environment is ready in the 'challenge/' directory." -ForegroundColor Cyan
|
||||
Write-Host "`nThis module uses a CHECKPOINT SYSTEM:" -ForegroundColor Yellow
|
||||
Write-Host " You'll work through 3 sections in one continuous repository:" -ForegroundColor White
|
||||
Write-Host " 1. Branching Basics (checkpoint: start)" -ForegroundColor White
|
||||
Write-Host " 2. Merging Branches (checkpoint: merge)" -ForegroundColor White
|
||||
Write-Host " 3. Resolving Merge Conflicts (checkpoint: merge-conflict)" -ForegroundColor White
|
||||
Write-Host "`nCommands:" -ForegroundColor Cyan
|
||||
Write-Host " .\reset.ps1 - Show available checkpoints" -ForegroundColor White
|
||||
Write-Host " .\reset.ps1 start - Jump to branching section" -ForegroundColor White
|
||||
Write-Host " .\reset.ps1 merge - Jump to merging section" -ForegroundColor White
|
||||
Write-Host " .\verify.ps1 - Verify all sections complete" -ForegroundColor White
|
||||
Write-Host " .\verify.ps1 start - Verify only branching section" -ForegroundColor White
|
||||
Write-Host "`nThe repository contains a realistic project history:" -ForegroundColor Yellow
|
||||
Write-Host " - Multiple feature branches (login, api, database)" -ForegroundColor White
|
||||
Write-Host " - All branches have been merged into main" -ForegroundColor White
|
||||
Write-Host " - View the history: git log --oneline --graph --all" -ForegroundColor White
|
||||
Write-Host "`nNext steps:" -ForegroundColor Cyan
|
||||
Write-Host " 1. Read the README.md for detailed instructions" -ForegroundColor White
|
||||
Write-Host " 2. cd challenge" -ForegroundColor White
|
||||
Write-Host " 3. Start with Checkpoint 1: Branching Basics" -ForegroundColor White
|
||||
Write-Host " 3. Explore the repository history: git log --oneline --graph --all" -ForegroundColor White
|
||||
Write-Host " 4. Create your own branches and practice merging!" -ForegroundColor White
|
||||
Write-Host ""
|
||||
|
||||
@@ -1,34 +1,15 @@
|
||||
#!/usr/bin/env pwsh
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Verifies the Module 03 challenge solution (checkpoint-aware).
|
||||
Verifies the Module 03 challenge solution.
|
||||
|
||||
.DESCRIPTION
|
||||
This script can verify completion of individual checkpoints or
|
||||
the entire module. Without arguments, it verifies all checkpoints.
|
||||
|
||||
.PARAMETER Checkpoint
|
||||
The checkpoint to verify: start, merge, or merge-conflict.
|
||||
If not specified, verifies all checkpoints.
|
||||
|
||||
.EXAMPLE
|
||||
.\verify.ps1
|
||||
Verifies all three checkpoints are complete.
|
||||
|
||||
.EXAMPLE
|
||||
.\verify.ps1 start
|
||||
Verifies only the branching basics checkpoint.
|
||||
|
||||
.EXAMPLE
|
||||
.\verify.ps1 merge
|
||||
Verifies only the merging checkpoint.
|
||||
This script checks that you've practiced branching and merging by:
|
||||
- Creating at least one new branch (beyond the example branches)
|
||||
- Making commits on your branch
|
||||
- Merging your branch into main
|
||||
#>
|
||||
|
||||
param(
|
||||
[ValidateSet('start', 'merge', 'merge-conflict', '')]
|
||||
[string]$Checkpoint = ''
|
||||
)
|
||||
|
||||
$script:allChecksPassed = $true
|
||||
|
||||
# ============================================================================
|
||||
@@ -51,198 +32,15 @@ function Write-Hint {
|
||||
Write-Host "[HINT] $Message" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Checkpoint 1: Branching Basics Verification
|
||||
# ============================================================================
|
||||
|
||||
function Verify-Branching {
|
||||
Write-Host "`n=== Checkpoint 1: Branching Basics ===" -ForegroundColor Cyan
|
||||
|
||||
# Save current branch
|
||||
$originalBranch = git branch --show-current 2>$null
|
||||
|
||||
# Check if feature-login branch exists
|
||||
$branchExists = git branch --list "feature-login" 2>$null
|
||||
if ($branchExists) {
|
||||
Write-Pass "Branch 'feature-login' exists"
|
||||
} else {
|
||||
Write-Fail "Branch 'feature-login' not found"
|
||||
Write-Hint "Create the branch with: git switch -c feature-login"
|
||||
return
|
||||
}
|
||||
|
||||
# Check if feature-login has commits beyond main (or if they've been merged)
|
||||
$commitCount = git rev-list main..feature-login --count 2>$null
|
||||
$mergeCommitExists = (git log --merges --oneline 2>$null | Select-String "Merge.*feature-login")
|
||||
|
||||
if ($mergeCommitExists -and $commitCount -eq 0) {
|
||||
# Commits were merged into main - this is correct!
|
||||
Write-Pass "Branch 'feature-login' commits have been merged into main"
|
||||
} elseif ($commitCount -ge 2) {
|
||||
Write-Pass "Branch 'feature-login' has $commitCount new commits"
|
||||
} else {
|
||||
Write-Fail "Branch 'feature-login' needs at least 2 new commits (found: $commitCount)"
|
||||
Write-Hint "Make sure you've committed login.py and made at least one more commit"
|
||||
}
|
||||
|
||||
# Switch to feature-login and check for login.py
|
||||
git switch feature-login 2>$null | Out-Null
|
||||
if (Test-Path "login.py") {
|
||||
Write-Pass "File 'login.py' exists in feature-login branch"
|
||||
} else {
|
||||
Write-Fail "File 'login.py' not found in feature-login branch"
|
||||
Write-Hint "Create login.py and commit it to the feature-login branch"
|
||||
}
|
||||
|
||||
# Switch to main and verify login.py doesn't exist there yet (unless merged)
|
||||
git switch main 2>$null | Out-Null
|
||||
|
||||
# Check if merge happened - if so, login.py can exist on main
|
||||
$mergeCommitExists = (git log --merges --oneline 2>$null | Select-String "Merge.*feature-login")
|
||||
|
||||
if (-not $mergeCommitExists) {
|
||||
# No merge yet - login.py should NOT be on main
|
||||
if (-not (Test-Path "login.py")) {
|
||||
Write-Pass "File 'login.py' does NOT exist in main branch (branches are independent!)"
|
||||
} else {
|
||||
Write-Fail "File 'login.py' should not exist in main branch yet (before merge)"
|
||||
Write-Hint "Make sure you created login.py only on the feature-login branch"
|
||||
}
|
||||
}
|
||||
|
||||
# Switch back to original branch
|
||||
if ($originalBranch) {
|
||||
git switch $originalBranch 2>$null | Out-Null
|
||||
}
|
||||
function Write-Info {
|
||||
param([string]$Message)
|
||||
Write-Host "[INFO] $Message" -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Checkpoint 2: Merging Verification
|
||||
# Check challenge directory exists
|
||||
# ============================================================================
|
||||
|
||||
function Verify-Merging {
|
||||
Write-Host "`n=== Checkpoint 2: Merging Branches ===" -ForegroundColor Cyan
|
||||
|
||||
# Check current branch is main
|
||||
$currentBranch = git branch --show-current 2>$null
|
||||
if ($currentBranch -eq "main") {
|
||||
Write-Pass "Currently on main branch"
|
||||
} else {
|
||||
Write-Fail "Should be on main branch (currently on: $currentBranch)"
|
||||
Write-Hint "Switch to main with: git switch main"
|
||||
}
|
||||
|
||||
# Check if login.py exists on main (indicates merge happened)
|
||||
if (Test-Path "login.py") {
|
||||
Write-Pass "File 'login.py' exists on main branch (merged successfully)"
|
||||
} else {
|
||||
Write-Fail "File 'login.py' not found on main branch"
|
||||
Write-Hint "Merge feature-login into main with: git merge feature-login"
|
||||
}
|
||||
|
||||
# Check for merge commit
|
||||
$mergeCommitExists = (git log --merges --oneline 2>$null | Select-String "Merge.*feature-login")
|
||||
|
||||
if ($mergeCommitExists) {
|
||||
Write-Pass "Merge commit exists"
|
||||
} else {
|
||||
Write-Fail "No merge commit found"
|
||||
Write-Hint "Create a merge commit with: git merge feature-login"
|
||||
}
|
||||
|
||||
# Check commit count (should have both branches' commits)
|
||||
$commitCount = [int](git rev-list --count HEAD 2>$null)
|
||||
if ($commitCount -ge 6) {
|
||||
Write-Pass "Repository has $commitCount commits (merge complete)"
|
||||
} else {
|
||||
Write-Fail "Repository should have at least 6 commits after merge (found: $commitCount)"
|
||||
}
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Checkpoint 3: Merge Conflicts Verification
|
||||
# ============================================================================
|
||||
|
||||
function Verify-MergeConflicts {
|
||||
Write-Host "`n=== Checkpoint 3: Resolving Merge Conflicts ===" -ForegroundColor Cyan
|
||||
|
||||
# Check current branch is main
|
||||
$currentBranch = git branch --show-current 2>$null
|
||||
if ($currentBranch -eq "main") {
|
||||
Write-Pass "Currently on main branch"
|
||||
} else {
|
||||
Write-Fail "Should be on main branch (currently on: $currentBranch)"
|
||||
Write-Hint "Switch to main with: git switch main"
|
||||
}
|
||||
|
||||
# Check that merge is not in progress
|
||||
if (Test-Path ".git/MERGE_HEAD") {
|
||||
Write-Fail "Merge is still in progress (conflicts not resolved)"
|
||||
Write-Hint "Resolve conflicts in config.json, then: git add config.json && git commit"
|
||||
return
|
||||
} else {
|
||||
Write-Pass "No merge in progress (conflicts resolved)"
|
||||
}
|
||||
|
||||
# Check if config.json exists
|
||||
if (Test-Path "config.json") {
|
||||
Write-Pass "File 'config.json' exists"
|
||||
} else {
|
||||
Write-Fail "File 'config.json' not found"
|
||||
Write-Hint "Merge update-config branch with: git merge update-config"
|
||||
return
|
||||
}
|
||||
|
||||
# Verify config.json is valid JSON
|
||||
try {
|
||||
$configContent = Get-Content "config.json" -Raw
|
||||
$config = $configContent | ConvertFrom-Json -ErrorAction Stop
|
||||
Write-Pass "File 'config.json' is valid JSON"
|
||||
} catch {
|
||||
Write-Fail "File 'config.json' is not valid JSON"
|
||||
Write-Hint "Make sure you removed all conflict markers (<<<<<<<, =======, >>>>>>>)"
|
||||
return
|
||||
}
|
||||
|
||||
# Check for conflict markers
|
||||
if ($configContent -match '<<<<<<<|=======|>>>>>>>') {
|
||||
Write-Fail "Conflict markers still present in config.json"
|
||||
Write-Hint "Remove all conflict markers (<<<<<<<, =======, >>>>>>>)"
|
||||
return
|
||||
} else {
|
||||
Write-Pass "No conflict markers in config.json"
|
||||
}
|
||||
|
||||
# Verify both settings are present (timeout and debug)
|
||||
if ($config.app.timeout -eq 5000) {
|
||||
Write-Pass "Timeout setting preserved (5000)"
|
||||
} else {
|
||||
Write-Fail "Timeout setting missing or incorrect"
|
||||
Write-Hint "Keep the timeout: 5000 setting from main branch"
|
||||
}
|
||||
|
||||
if ($config.app.debug -eq $true) {
|
||||
Write-Pass "Debug setting preserved (true)"
|
||||
} else {
|
||||
Write-Fail "Debug setting missing or incorrect"
|
||||
Write-Hint "Keep the debug: true setting from update-config branch"
|
||||
}
|
||||
|
||||
# Verify merge commit exists for update-config
|
||||
$updateConfigMerge = (git log --merges --oneline 2>$null | Select-String "Merge.*update-config")
|
||||
if ($updateConfigMerge) {
|
||||
Write-Pass "Merge commit exists for update-config branch"
|
||||
} else {
|
||||
Write-Fail "No merge commit found for update-config"
|
||||
Write-Hint "Complete the merge with: git commit (after resolving conflicts)"
|
||||
}
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Main Script Logic
|
||||
# ============================================================================
|
||||
|
||||
# Check if challenge directory exists
|
||||
if (-not (Test-Path "challenge")) {
|
||||
Write-Host "[ERROR] Challenge directory not found." -ForegroundColor Red
|
||||
Write-Host "Run .\setup.ps1 first to create the challenge environment." -ForegroundColor Yellow
|
||||
@@ -251,7 +49,6 @@ if (-not (Test-Path "challenge")) {
|
||||
|
||||
Push-Location "challenge"
|
||||
|
||||
# Check if git repository exists
|
||||
if (-not (Test-Path ".git")) {
|
||||
Write-Host "[ERROR] Not a git repository." -ForegroundColor Red
|
||||
Write-Host "Run ..\setup.ps1 first to create the challenge environment." -ForegroundColor Yellow
|
||||
@@ -259,62 +56,98 @@ if (-not (Test-Path ".git")) {
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Run appropriate verification
|
||||
if ($Checkpoint -eq '') {
|
||||
# Verify all checkpoints
|
||||
Write-Host "`n=== Verifying All Checkpoints ===" -ForegroundColor Cyan
|
||||
Write-Host "`n=== Verifying Module 03: Branching and Merging ===" -ForegroundColor Cyan
|
||||
|
||||
Verify-Branching
|
||||
Verify-Merging
|
||||
Verify-MergeConflicts
|
||||
# ============================================================================
|
||||
# Count initial setup commits (should be 13 commits from setup)
|
||||
# ============================================================================
|
||||
$initialCommitCount = 13
|
||||
|
||||
# ============================================================================
|
||||
# Check for new commits beyond setup
|
||||
# ============================================================================
|
||||
Write-Host "`nChecking your work..." -ForegroundColor Cyan
|
||||
|
||||
$totalCommits = [int](git rev-list --count HEAD 2>$null)
|
||||
|
||||
if ($totalCommits -gt $initialCommitCount) {
|
||||
$newCommits = $totalCommits - $initialCommitCount
|
||||
Write-Pass "Found $newCommits new commit(s) beyond the initial setup"
|
||||
} else {
|
||||
# Verify specific checkpoint
|
||||
switch ($Checkpoint) {
|
||||
'start' { Verify-Branching }
|
||||
'merge' { Verify-Merging }
|
||||
'merge-conflict' { Verify-MergeConflicts }
|
||||
}
|
||||
Write-Fail "No new commits found"
|
||||
Write-Hint "Create a branch, make some commits, and merge it into main"
|
||||
Write-Hint "Example: git switch -c my-feature"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Check for branches (excluding the example branches)
|
||||
# ============================================================================
|
||||
$allBranches = git branch --list 2>$null | ForEach-Object { $_.Trim('* ') }
|
||||
$exampleBranches = @('main', 'feature-login', 'feature-api', 'feature-database')
|
||||
$studentBranches = $allBranches | Where-Object { $_ -notin $exampleBranches }
|
||||
|
||||
if ($studentBranches.Count -gt 0) {
|
||||
Write-Pass "Created $($studentBranches.Count) new branch(es): $($studentBranches -join ', ')"
|
||||
} else {
|
||||
Write-Info "No new branches found (it's OK if you deleted them after merging)"
|
||||
Write-Hint "To practice: git switch -c your-branch-name"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Check for merge commits by the student
|
||||
# ============================================================================
|
||||
$setupUser = "Workshop Student"
|
||||
$mergeCommits = git log --merges --format="%s" 2>$null
|
||||
|
||||
# Count how many merge commits exist beyond the initial 3
|
||||
$totalMerges = ($mergeCommits | Measure-Object).Count
|
||||
$setupMerges = 3 # feature-login, feature-api, feature-database
|
||||
|
||||
if ($totalMerges -gt $setupMerges) {
|
||||
$studentMerges = $totalMerges - $setupMerges
|
||||
Write-Pass "Performed $studentMerges merge(s) of your own work"
|
||||
} else {
|
||||
Write-Fail "No merge commits found beyond the example merges"
|
||||
Write-Hint "Create a branch, add commits, then merge it: git merge your-branch-name"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Check current branch
|
||||
# ============================================================================
|
||||
$currentBranch = git branch --show-current 2>$null
|
||||
if ($currentBranch -eq "main") {
|
||||
Write-Pass "Currently on main branch"
|
||||
} else {
|
||||
Write-Info "Currently on '$currentBranch' branch"
|
||||
Write-Hint "Typically you merge feature branches INTO main"
|
||||
}
|
||||
|
||||
Pop-Location
|
||||
|
||||
# ============================================================================
|
||||
# Final summary
|
||||
# ============================================================================
|
||||
Write-Host ""
|
||||
if ($script:allChecksPassed) {
|
||||
Write-Host "=========================================" -ForegroundColor Green
|
||||
Write-Host " CONGRATULATIONS! CHALLENGE PASSED!" -ForegroundColor Green
|
||||
Write-Host "=========================================" -ForegroundColor Green
|
||||
|
||||
if ($Checkpoint -eq '') {
|
||||
Write-Host "`nYou've completed the entire module!" -ForegroundColor Cyan
|
||||
Write-Host "You've mastered:" -ForegroundColor Cyan
|
||||
Write-Host " ✓ Creating and working with branches" -ForegroundColor White
|
||||
Write-Host " ✓ Merging branches together" -ForegroundColor White
|
||||
Write-Host " ✓ Resolving merge conflicts" -ForegroundColor White
|
||||
Write-Host "`nReady for the next module!" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "`nCheckpoint '$Checkpoint' complete!" -ForegroundColor Cyan
|
||||
|
||||
switch ($Checkpoint) {
|
||||
'start' {
|
||||
Write-Host "Next: Move to the merging checkpoint" -ForegroundColor White
|
||||
Write-Host " ..\reset.ps1 merge OR continue to merge feature-login" -ForegroundColor Yellow
|
||||
}
|
||||
'merge' {
|
||||
Write-Host "Next: Move to the conflict resolution checkpoint" -ForegroundColor White
|
||||
Write-Host " ..\reset.ps1 merge-conflict" -ForegroundColor Yellow
|
||||
}
|
||||
'merge-conflict' {
|
||||
Write-Host "Module complete! Ready for the next module!" -ForegroundColor Green
|
||||
}
|
||||
}
|
||||
}
|
||||
Write-Host "`nYou've successfully practiced:" -ForegroundColor Cyan
|
||||
Write-Host " ✓ Creating branches" -ForegroundColor White
|
||||
Write-Host " ✓ Making commits on branches" -ForegroundColor White
|
||||
Write-Host " ✓ Merging branches together" -ForegroundColor White
|
||||
Write-Host "`nReady for the next module!" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
exit 0
|
||||
} else {
|
||||
Write-Host "[SUMMARY] Some checks failed. Review the hints above and try again." -ForegroundColor Red
|
||||
Write-Host "[INFO] You can run this verification script as many times as needed." -ForegroundColor Yellow
|
||||
Write-Host "[SUMMARY] Some checks failed. Review the hints above." -ForegroundColor Red
|
||||
Write-Host ""
|
||||
Write-Host "Quick guide:" -ForegroundColor Cyan
|
||||
Write-Host " 1. Create a branch: git switch -c my-feature" -ForegroundColor White
|
||||
Write-Host " 2. Make changes and commit them" -ForegroundColor White
|
||||
Write-Host " 3. Switch to main: git switch main" -ForegroundColor White
|
||||
Write-Host " 4. Merge your branch: git merge my-feature" -ForegroundColor White
|
||||
Write-Host " 5. Run this verify script again" -ForegroundColor White
|
||||
Write-Host ""
|
||||
exit 1
|
||||
}
|
||||
|
||||
487
01-essentials/04-merge-conflict/README.md
Normal file
487
01-essentials/04-merge-conflict/README.md
Normal file
@@ -0,0 +1,487 @@
|
||||
# Module 04: Merge Conflicts
|
||||
|
||||
## Learning Objectives
|
||||
|
||||
By the end of this module, you will:
|
||||
- Understand what merge conflicts are and why they occur
|
||||
- Use `git diff` to discover changes between branches
|
||||
- Identify merge conflicts in your repository
|
||||
- Read and interpret conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`)
|
||||
- Resolve merge conflicts manually
|
||||
- Complete a merge after resolving conflicts
|
||||
|
||||
## Setup
|
||||
|
||||
Create the challenge environment:
|
||||
|
||||
```bash
|
||||
.\setup.ps1
|
||||
```
|
||||
|
||||
This creates a repository with two feature branches that have conflicting changes.
|
||||
|
||||
## Overview
|
||||
|
||||
A **merge conflict** occurs when Git cannot automatically combine changes because both branches modified the same part of the same file in different ways.
|
||||
|
||||
**When do conflicts happen?**
|
||||
- ✅ Two branches modify the same lines in a file
|
||||
- ✅ One branch deletes a file that another branch modifies
|
||||
- ✅ Complex changes Git can't merge automatically
|
||||
- ❌ Different files are changed (no conflict!)
|
||||
- ❌ Different parts of the same file are changed (no conflict!)
|
||||
|
||||
**Don't fear conflicts!** They're a normal part of collaborative development. Git just needs your help to decide what the final code should look like.
|
||||
|
||||
## Your Task
|
||||
|
||||
### Part 1: Discover the Changes
|
||||
|
||||
Before merging, it's good practice to see what each branch changed:
|
||||
|
||||
```bash
|
||||
cd challenge
|
||||
|
||||
# Check which branch you're on
|
||||
git branch
|
||||
|
||||
# View all branches
|
||||
git branch --all
|
||||
```
|
||||
|
||||
You'll see three branches: `main`, `add-timeout`, and `add-debug`.
|
||||
|
||||
**Discover what each branch changed:**
|
||||
|
||||
```bash
|
||||
# Compare main with add-timeout
|
||||
git diff main add-timeout
|
||||
|
||||
# Compare main with add-debug
|
||||
git diff main add-debug
|
||||
|
||||
# Compare the two feature branches directly
|
||||
git diff add-timeout add-debug
|
||||
```
|
||||
|
||||
**What did you discover?**
|
||||
- Both branches modified `config.json`
|
||||
- They both added a line in the same location (after `"port": 3000`)
|
||||
- One adds `"timeout": 5000`
|
||||
- The other adds `"debug": true`
|
||||
|
||||
This is a recipe for a conflict!
|
||||
|
||||
### Part 2: Merge the First Branch (No Conflict)
|
||||
|
||||
Let's merge `add-timeout` first:
|
||||
|
||||
```bash
|
||||
# Make sure you're on main
|
||||
git switch main
|
||||
|
||||
# Merge the first branch
|
||||
git merge add-timeout
|
||||
```
|
||||
|
||||
✅ **Success!** This merge works because main hasn't changed since add-timeout was created.
|
||||
|
||||
```bash
|
||||
# View the updated config
|
||||
cat config.json
|
||||
|
||||
# Check the history
|
||||
git log --oneline --graph --all
|
||||
```
|
||||
|
||||
### Part 3: Try to Merge the Second Branch (Conflict!)
|
||||
|
||||
Now let's try to merge `add-debug`:
|
||||
|
||||
```bash
|
||||
# Still on main
|
||||
git merge add-debug
|
||||
```
|
||||
|
||||
💥 **Boom!** You'll see:
|
||||
|
||||
```
|
||||
Auto-merging config.json
|
||||
CONFLICT (content): Merge conflict in config.json
|
||||
Automatic merge failed; fix conflicts and then commit the result.
|
||||
```
|
||||
|
||||
**Don't panic!** This is expected. Git is asking for your help.
|
||||
|
||||
### Part 4: Check the Status
|
||||
|
||||
```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.json
|
||||
```
|
||||
|
||||
This tells you that `config.json` needs your attention!
|
||||
|
||||
### Part 5: Open and Examine the Conflicted File
|
||||
|
||||
Open `config.json` in your text editor:
|
||||
|
||||
```bash
|
||||
# On Windows
|
||||
notepad config.json
|
||||
|
||||
# Or use VS Code
|
||||
code config.json
|
||||
```
|
||||
|
||||
You'll see special **conflict markers**:
|
||||
|
||||
```json
|
||||
{
|
||||
"app": {
|
||||
"name": "MyApp",
|
||||
"version": "1.0.0",
|
||||
"port": 3000,
|
||||
<<<<<<< HEAD
|
||||
"timeout": 5000
|
||||
=======
|
||||
"debug": true
|
||||
>>>>>>> add-debug
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Part 6: Understand the Conflict Markers
|
||||
|
||||
Let's break down what you're seeing:
|
||||
|
||||
```
|
||||
<<<<<<< HEAD
|
||||
"timeout": 5000 ← Your current branch (main, which has add-timeout merged)
|
||||
=======
|
||||
"debug": true ← The branch you're merging (add-debug)
|
||||
>>>>>>> add-debug
|
||||
```
|
||||
|
||||
**What each marker means:**
|
||||
- `<<<<<<< HEAD` - Start of your changes (current branch)
|
||||
- `=======` - Separator between the two versions
|
||||
- `>>>>>>> add-debug` - End of their changes (branch being merged)
|
||||
|
||||
### Part 7: Resolve the Conflict
|
||||
|
||||
You have three options:
|
||||
|
||||
**Option 1: Keep ONLY your changes (timeout)**
|
||||
```json
|
||||
"timeout": 5000
|
||||
```
|
||||
|
||||
**Option 2: Keep ONLY their changes (debug)**
|
||||
```json
|
||||
"debug": true
|
||||
```
|
||||
|
||||
**Option 3: Keep BOTH changes** ← **Do this!**
|
||||
```json
|
||||
"timeout": 5000,
|
||||
"debug": true
|
||||
```
|
||||
|
||||
### Part 8: Edit the File
|
||||
|
||||
For this challenge, we want **both settings**, so:
|
||||
|
||||
1. Delete ALL the conflict markers:
|
||||
- Remove `<<<<<<< HEAD`
|
||||
- Remove `=======`
|
||||
- Remove `>>>>>>> add-debug`
|
||||
|
||||
2. Keep both settings:
|
||||
|
||||
**Before (with conflict markers):**
|
||||
```json
|
||||
{
|
||||
"app": {
|
||||
"name": "MyApp",
|
||||
"version": "1.0.0",
|
||||
"port": 3000,
|
||||
<<<<<<< HEAD
|
||||
"timeout": 5000
|
||||
=======
|
||||
"debug": true
|
||||
>>>>>>> add-debug
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**After (resolved):**
|
||||
```json
|
||||
{
|
||||
"app": {
|
||||
"name": "MyApp",
|
||||
"version": "1.0.0",
|
||||
"port": 3000,
|
||||
"timeout": 5000,
|
||||
"debug": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Important:**
|
||||
- Remove ALL markers
|
||||
- Add a comma after `"timeout": 5000` (for valid JSON)
|
||||
- Ensure the file is valid JSON
|
||||
|
||||
3. Save the file
|
||||
|
||||
### Part 9: Mark the Conflict as Resolved
|
||||
|
||||
Tell Git you've resolved the conflict:
|
||||
|
||||
```bash
|
||||
# Stage the resolved file
|
||||
git add config.json
|
||||
|
||||
# Check status
|
||||
git status
|
||||
```
|
||||
|
||||
You should see:
|
||||
|
||||
```
|
||||
On branch main
|
||||
All conflicts fixed but you are still merging.
|
||||
(use "git commit" to conclude merge)
|
||||
```
|
||||
|
||||
Perfect! Git confirms the conflict is resolved.
|
||||
|
||||
### Part 10: Complete the Merge
|
||||
|
||||
Commit the merge:
|
||||
|
||||
```bash
|
||||
git commit
|
||||
```
|
||||
|
||||
Git will open an editor with a default merge message. You can accept it or customize it, then save and close.
|
||||
|
||||
**Done!** Your merge is complete!
|
||||
|
||||
```bash
|
||||
# View the final result
|
||||
cat config.json
|
||||
|
||||
# View the history
|
||||
git log --oneline --graph --all
|
||||
```
|
||||
|
||||
You should see both `timeout` and `debug` in the config!
|
||||
|
||||
### Part 11: Verify Your Solution
|
||||
|
||||
From the module directory (not inside challenge/):
|
||||
|
||||
```bash
|
||||
.\verify.ps1
|
||||
```
|
||||
|
||||
## Understanding Conflict Markers
|
||||
|
||||
### Anatomy of a Conflict
|
||||
|
||||
```
|
||||
<<<<<<< HEAD ← Marker: Start of your version
|
||||
Your changes here
|
||||
======= ← Marker: Separator
|
||||
Their changes here
|
||||
>>>>>>> branch-name ← Marker: End of their version
|
||||
```
|
||||
|
||||
### Common Conflict Patterns
|
||||
|
||||
**Simple conflict:**
|
||||
```
|
||||
<<<<<<< HEAD
|
||||
print("Hello")
|
||||
=======
|
||||
print("Hi")
|
||||
>>>>>>> feature
|
||||
```
|
||||
Decision: Which greeting do you want?
|
||||
|
||||
**Both are needed:**
|
||||
```
|
||||
<<<<<<< HEAD
|
||||
timeout: 5000
|
||||
=======
|
||||
debug: true
|
||||
>>>>>>> feature
|
||||
```
|
||||
Decision: Keep both (add comma)!
|
||||
|
||||
**Deletion conflict:**
|
||||
```
|
||||
<<<<<<< HEAD
|
||||
# Function deleted on your branch
|
||||
=======
|
||||
def old_function():
|
||||
pass
|
||||
>>>>>>> feature
|
||||
```
|
||||
Decision: Delete or keep the function?
|
||||
|
||||
## Common Mistakes to Avoid
|
||||
|
||||
❌ **Forgetting to remove conflict markers**
|
||||
```json
|
||||
<<<<<<< HEAD ← Don't leave these in!
|
||||
"timeout": 5000,
|
||||
"debug": true
|
||||
>>>>>>> add-debug ← Don't leave these in!
|
||||
```
|
||||
This breaks your code! Always remove ALL markers.
|
||||
|
||||
❌ **Committing without staging**
|
||||
```bash
|
||||
git commit # Error! You didn't add the file
|
||||
```
|
||||
Always `git add` the resolved file first!
|
||||
|
||||
❌ **Keeping only one side when both are needed**
|
||||
If you delete one setting, you lose that work!
|
||||
|
||||
❌ **Breaking syntax**
|
||||
```json
|
||||
"timeout": 5000 ← Missing comma!
|
||||
"debug": true
|
||||
```
|
||||
Always verify your file is valid after resolving!
|
||||
|
||||
❌ **Not testing the result**
|
||||
Always check that your resolved code works!
|
||||
|
||||
## Aborting a Merge
|
||||
|
||||
Changed your mind? You can abort the merge anytime before committing:
|
||||
|
||||
```bash
|
||||
git merge --abort
|
||||
```
|
||||
|
||||
This returns your repository to the state before you started the merge. No harm done!
|
||||
|
||||
## Key Commands
|
||||
|
||||
```bash
|
||||
# Discover changes before merging
|
||||
git diff branch1 branch2
|
||||
|
||||
# Attempt a merge
|
||||
git merge <branch-name>
|
||||
|
||||
# Check which files have conflicts
|
||||
git status
|
||||
|
||||
# Abort the merge and start over
|
||||
git merge --abort
|
||||
|
||||
# After resolving conflicts:
|
||||
git add <resolved-file>
|
||||
git commit
|
||||
|
||||
# View conflicts in a different style
|
||||
git diff --ours # Your changes
|
||||
git diff --theirs # Their changes
|
||||
git diff --base # Original version
|
||||
```
|
||||
|
||||
## Pro Tips
|
||||
|
||||
💡 **Use `git diff` first**
|
||||
Always compare branches before merging:
|
||||
```bash
|
||||
git diff main..feature-branch
|
||||
```
|
||||
|
||||
💡 **Prevent conflicts**
|
||||
- Pull changes frequently
|
||||
- Communicate with your team about who's working on what
|
||||
- Keep branches short-lived and merge often
|
||||
|
||||
💡 **Make conflicts easier**
|
||||
- Work on different files when possible
|
||||
- Make small, focused commits
|
||||
- If editing the same file, coordinate with teammates
|
||||
|
||||
💡 **When stuck**
|
||||
- Read the conflict markers carefully
|
||||
- Look at `git log` to understand what each side changed
|
||||
- Use `git diff` to see the changes
|
||||
- Ask a teammate to review your resolution
|
||||
- Use a merge tool: `git mergetool`
|
||||
|
||||
## Merge Tools
|
||||
|
||||
Git supports visual merge tools that make resolving conflicts easier:
|
||||
|
||||
```bash
|
||||
# Configure a merge tool (one-time setup)
|
||||
git config --global merge.tool vscode # or meld, kdiff3, etc.
|
||||
|
||||
# Use the merge tool during a conflict
|
||||
git mergetool
|
||||
```
|
||||
|
||||
This opens a visual interface showing both versions side-by-side.
|
||||
|
||||
## Real-World Scenario
|
||||
|
||||
This exercise simulates a common real-world situation:
|
||||
|
||||
**Scenario:** Two developers working on the same file
|
||||
- Alice adds a timeout configuration
|
||||
- Bob adds debug mode configuration
|
||||
- Both push their changes
|
||||
- When Bob tries to merge, he gets a conflict
|
||||
- Bob resolves it by keeping both changes
|
||||
- Everyone's work is preserved!
|
||||
|
||||
This happens all the time in team development. Conflicts are normal!
|
||||
|
||||
## What You've Learned
|
||||
|
||||
After completing this module, you understand:
|
||||
|
||||
- ✅ Merge conflicts happen when the same lines are changed differently
|
||||
- ✅ `git diff` helps you discover changes before merging
|
||||
- ✅ Conflict markers show both versions
|
||||
- ✅ You decide what the final code should look like
|
||||
- ✅ Remove all markers before committing
|
||||
- ✅ Test your resolution to ensure it works
|
||||
- ✅ Conflicts are normal and easy to resolve with practice
|
||||
|
||||
## Next Steps
|
||||
|
||||
Ready to continue? The next module covers **cherry-picking** - selectively applying specific commits from one branch to another.
|
||||
|
||||
To start over:
|
||||
```bash
|
||||
.\reset.ps1
|
||||
.\setup.ps1
|
||||
```
|
||||
|
||||
**Need help?** Review the steps above, or run `git status` to see what Git suggests!
|
||||
1
01-essentials/04-merge-conflict/challenge
Submodule
1
01-essentials/04-merge-conflict/challenge
Submodule
Submodule 01-essentials/04-merge-conflict/challenge added at 676b08e650
23
01-essentials/04-merge-conflict/reset.ps1
Normal file
23
01-essentials/04-merge-conflict/reset.ps1
Normal file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env pwsh
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Resets the Module 04 challenge environment.
|
||||
|
||||
.DESCRIPTION
|
||||
This script removes the challenge directory, allowing you to start fresh.
|
||||
Run setup.ps1 again after resetting to recreate the environment.
|
||||
#>
|
||||
|
||||
Write-Host "`n=== Resetting Module 04 Challenge ===" -ForegroundColor Cyan
|
||||
|
||||
if (Test-Path "challenge") {
|
||||
Write-Host "Removing challenge directory..." -ForegroundColor Yellow
|
||||
Remove-Item -Recurse -Force "challenge"
|
||||
Write-Host "`n[SUCCESS] Challenge environment reset complete!" -ForegroundColor Green
|
||||
Write-Host "`nRun .\setup.ps1 to create a fresh challenge environment." -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
} else {
|
||||
Write-Host "`n[INFO] No challenge directory found. Nothing to reset." -ForegroundColor Yellow
|
||||
Write-Host "Run .\setup.ps1 to create the challenge environment." -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
}
|
||||
125
01-essentials/04-merge-conflict/setup.ps1
Normal file
125
01-essentials/04-merge-conflict/setup.ps1
Normal file
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env pwsh
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Sets up the Module 04 challenge environment for merge conflicts.
|
||||
|
||||
.DESCRIPTION
|
||||
This script creates a challenge directory with a Git repository containing
|
||||
two feature branches that have conflicting changes to the same file.
|
||||
Students will learn to identify, understand, and resolve merge conflicts.
|
||||
#>
|
||||
|
||||
Write-Host "`n=== Setting up Module 04: Merge Conflicts ===" -ForegroundColor Cyan
|
||||
|
||||
# Remove existing challenge directory if it exists
|
||||
if (Test-Path "challenge") {
|
||||
Write-Host "Removing existing challenge directory..." -ForegroundColor Yellow
|
||||
Remove-Item -Recurse -Force "challenge"
|
||||
}
|
||||
|
||||
# Create fresh challenge directory
|
||||
Write-Host "Creating challenge directory..." -ForegroundColor Green
|
||||
New-Item -ItemType Directory -Path "challenge" | Out-Null
|
||||
Set-Location "challenge"
|
||||
|
||||
# Initialize Git repository
|
||||
Write-Host "Initializing Git repository..." -ForegroundColor Green
|
||||
git init | Out-Null
|
||||
|
||||
# Configure git for this repository
|
||||
git config user.name "Workshop Student"
|
||||
git config user.email "student@example.com"
|
||||
|
||||
# ============================================================================
|
||||
# Create base project
|
||||
# ============================================================================
|
||||
Write-Host "Creating base project..." -ForegroundColor Cyan
|
||||
|
||||
# Initial commit with config file
|
||||
$configContent = @"
|
||||
{
|
||||
"app": {
|
||||
"name": "MyApp",
|
||||
"version": "1.0.0",
|
||||
"port": 3000
|
||||
}
|
||||
}
|
||||
"@
|
||||
Set-Content -Path "config.json" -Value $configContent
|
||||
git add .
|
||||
git commit -m "Initial commit with config" | Out-Null
|
||||
|
||||
# Add README
|
||||
$readmeContent = @"
|
||||
# My Application
|
||||
|
||||
A simple application for learning merge conflicts.
|
||||
|
||||
## Configuration
|
||||
|
||||
Edit `config.json` to configure the application.
|
||||
"@
|
||||
Set-Content -Path "README.md" -Value $readmeContent
|
||||
git add .
|
||||
git commit -m "Add README" | Out-Null
|
||||
|
||||
# ============================================================================
|
||||
# Branch 1: add-timeout (adds timeout setting)
|
||||
# ============================================================================
|
||||
Write-Host "Creating add-timeout branch..." -ForegroundColor Cyan
|
||||
git switch -c add-timeout | Out-Null
|
||||
|
||||
$timeoutConfig = @"
|
||||
{
|
||||
"app": {
|
||||
"name": "MyApp",
|
||||
"version": "1.0.0",
|
||||
"port": 3000,
|
||||
"timeout": 5000
|
||||
}
|
||||
}
|
||||
"@
|
||||
Set-Content -Path "config.json" -Value $timeoutConfig
|
||||
git add .
|
||||
git commit -m "Add timeout configuration" | Out-Null
|
||||
|
||||
# ============================================================================
|
||||
# Branch 2: add-debug (adds debug setting - CONFLICTS with timeout!)
|
||||
# ============================================================================
|
||||
Write-Host "Creating add-debug branch..." -ForegroundColor Cyan
|
||||
git switch main | Out-Null
|
||||
git switch -c add-debug | Out-Null
|
||||
|
||||
$debugConfig = @"
|
||||
{
|
||||
"app": {
|
||||
"name": "MyApp",
|
||||
"version": "1.0.0",
|
||||
"port": 3000,
|
||||
"debug": true
|
||||
}
|
||||
}
|
||||
"@
|
||||
Set-Content -Path "config.json" -Value $debugConfig
|
||||
git add .
|
||||
git commit -m "Add debug mode configuration" | Out-Null
|
||||
|
||||
# Switch back to main
|
||||
git switch main | Out-Null
|
||||
|
||||
# Return to module directory
|
||||
Set-Location ..
|
||||
|
||||
Write-Host "`n=== Setup Complete! ===" -ForegroundColor Green
|
||||
Write-Host "`nYour challenge environment is ready in the 'challenge/' directory." -ForegroundColor Cyan
|
||||
Write-Host "`nThe repository contains:" -ForegroundColor Yellow
|
||||
Write-Host " - main branch: base configuration" -ForegroundColor White
|
||||
Write-Host " - add-timeout branch: adds timeout setting" -ForegroundColor White
|
||||
Write-Host " - add-debug branch: adds debug setting" -ForegroundColor White
|
||||
Write-Host "`nBoth branches modify the same part of config.json!" -ForegroundColor Red
|
||||
Write-Host "This will cause a merge conflict when you try to merge both." -ForegroundColor Red
|
||||
Write-Host "`nNext steps:" -ForegroundColor Cyan
|
||||
Write-Host " 1. Read the README.md for detailed instructions" -ForegroundColor White
|
||||
Write-Host " 2. cd challenge" -ForegroundColor White
|
||||
Write-Host " 3. Follow the guide to discover and resolve the conflict" -ForegroundColor White
|
||||
Write-Host ""
|
||||
208
01-essentials/04-merge-conflict/verify.ps1
Normal file
208
01-essentials/04-merge-conflict/verify.ps1
Normal file
@@ -0,0 +1,208 @@
|
||||
#!/usr/bin/env pwsh
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Verifies the Module 04 challenge solution.
|
||||
|
||||
.DESCRIPTION
|
||||
This script checks that you've successfully resolved the merge conflict by:
|
||||
- Merging both branches into main
|
||||
- Resolving the conflict in config.json
|
||||
- Keeping both timeout and debug settings
|
||||
- Ensuring valid JSON syntax
|
||||
#>
|
||||
|
||||
$script:allChecksPassed = $true
|
||||
|
||||
# ============================================================================
|
||||
# Helper Functions
|
||||
# ============================================================================
|
||||
|
||||
function Write-Pass {
|
||||
param([string]$Message)
|
||||
Write-Host "[PASS] $Message" -ForegroundColor Green
|
||||
}
|
||||
|
||||
function Write-Fail {
|
||||
param([string]$Message)
|
||||
Write-Host "[FAIL] $Message" -ForegroundColor Red
|
||||
$script:allChecksPassed = $false
|
||||
}
|
||||
|
||||
function Write-Hint {
|
||||
param([string]$Message)
|
||||
Write-Host "[HINT] $Message" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
function Write-Info {
|
||||
param([string]$Message)
|
||||
Write-Host "[INFO] $Message" -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Check challenge directory exists
|
||||
# ============================================================================
|
||||
|
||||
if (-not (Test-Path "challenge")) {
|
||||
Write-Host "[ERROR] Challenge directory not found." -ForegroundColor Red
|
||||
Write-Host "Run .\setup.ps1 first to create the challenge environment." -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
|
||||
Push-Location "challenge"
|
||||
|
||||
if (-not (Test-Path ".git")) {
|
||||
Write-Host "[ERROR] Not a git repository." -ForegroundColor Red
|
||||
Write-Host "Run ..\setup.ps1 first to create the challenge environment." -ForegroundColor Yellow
|
||||
Pop-Location
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "`n=== Verifying Module 04: Merge Conflicts ===" -ForegroundColor Cyan
|
||||
|
||||
# ============================================================================
|
||||
# Check current branch
|
||||
# ============================================================================
|
||||
$currentBranch = git branch --show-current 2>$null
|
||||
if ($currentBranch -eq "main") {
|
||||
Write-Pass "Currently on main branch"
|
||||
} else {
|
||||
Write-Fail "Should be on main branch (currently on: $currentBranch)"
|
||||
Write-Hint "Switch to main with: git switch main"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Check that merge is not in progress
|
||||
# ============================================================================
|
||||
if (Test-Path ".git/MERGE_HEAD") {
|
||||
Write-Fail "Merge is still in progress (conflicts not resolved)"
|
||||
Write-Hint "Resolve conflicts in config.json, then: git add config.json && git commit"
|
||||
Pop-Location
|
||||
exit 1
|
||||
} else {
|
||||
Write-Pass "No merge in progress (conflicts resolved)"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Check if config.json exists
|
||||
# ============================================================================
|
||||
if (-not (Test-Path "config.json")) {
|
||||
Write-Fail "File 'config.json' not found"
|
||||
Write-Hint "The config.json file should exist"
|
||||
Pop-Location
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Verify config.json is valid JSON
|
||||
# ============================================================================
|
||||
try {
|
||||
$configContent = Get-Content "config.json" -Raw
|
||||
$config = $configContent | ConvertFrom-Json -ErrorAction Stop
|
||||
Write-Pass "File 'config.json' is valid JSON"
|
||||
} catch {
|
||||
Write-Fail "File 'config.json' is not valid JSON"
|
||||
Write-Hint "Make sure you removed all conflict markers (<<<<<<<, =======, >>>>>>>)"
|
||||
Write-Hint "Check for missing commas or brackets"
|
||||
Pop-Location
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Check for conflict markers
|
||||
# ============================================================================
|
||||
if ($configContent -match '<<<<<<<|=======|>>>>>>>') {
|
||||
Write-Fail "Conflict markers still present in config.json"
|
||||
Write-Hint "Remove all conflict markers (<<<<<<<, =======, >>>>>>>)"
|
||||
Pop-Location
|
||||
exit 1
|
||||
} else {
|
||||
Write-Pass "No conflict markers in config.json"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Verify both settings are present (timeout and debug)
|
||||
# ============================================================================
|
||||
if ($config.app.timeout -eq 5000) {
|
||||
Write-Pass "Timeout setting preserved (5000)"
|
||||
} else {
|
||||
Write-Fail "Timeout setting missing or incorrect"
|
||||
Write-Hint "Keep the timeout: 5000 setting from add-timeout branch"
|
||||
}
|
||||
|
||||
if ($config.app.debug -eq $true) {
|
||||
Write-Pass "Debug setting preserved (true)"
|
||||
} else {
|
||||
Write-Fail "Debug setting missing or incorrect"
|
||||
Write-Hint "Keep the debug: true setting from add-debug branch"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Verify both branches were merged
|
||||
# ============================================================================
|
||||
$addTimeoutMerged = git log --oneline --grep="add-timeout" 2>$null | Select-String "Merge"
|
||||
$addDebugMerged = git log --oneline --grep="add-debug" 2>$null | Select-String "Merge"
|
||||
|
||||
if ($addTimeoutMerged) {
|
||||
Write-Pass "add-timeout branch has been merged"
|
||||
} else {
|
||||
# Check if it was a fast-forward merge (commits exist but no merge commit)
|
||||
$timeoutCommit = git log --oneline --grep="Add timeout configuration" 2>$null
|
||||
if ($timeoutCommit) {
|
||||
Write-Pass "add-timeout branch changes are in main"
|
||||
} else {
|
||||
Write-Fail "add-timeout branch not merged"
|
||||
Write-Hint "Merge with: git merge add-timeout"
|
||||
}
|
||||
}
|
||||
|
||||
if ($addDebugMerged) {
|
||||
Write-Pass "add-debug branch has been merged"
|
||||
} else {
|
||||
Write-Fail "add-debug branch not merged"
|
||||
Write-Hint "Merge with: git merge add-debug"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Check commit count (should have both merges)
|
||||
# ============================================================================
|
||||
$totalCommits = [int](git rev-list --count HEAD 2>$null)
|
||||
if ($totalCommits -ge 5) {
|
||||
Write-Pass "Repository has $totalCommits commits (all merges complete)"
|
||||
} else {
|
||||
Write-Info "Repository has $totalCommits commits"
|
||||
Write-Hint "Make sure both branches are merged"
|
||||
}
|
||||
|
||||
Pop-Location
|
||||
|
||||
# ============================================================================
|
||||
# Final summary
|
||||
# ============================================================================
|
||||
Write-Host ""
|
||||
if ($script:allChecksPassed) {
|
||||
Write-Host "=========================================" -ForegroundColor Green
|
||||
Write-Host " CONGRATULATIONS! CHALLENGE PASSED!" -ForegroundColor Green
|
||||
Write-Host "=========================================" -ForegroundColor Green
|
||||
Write-Host "`nYou've successfully:" -ForegroundColor Cyan
|
||||
Write-Host " ✓ Discovered changes using git diff" -ForegroundColor White
|
||||
Write-Host " ✓ Merged the first branch" -ForegroundColor White
|
||||
Write-Host " ✓ Encountered a merge conflict" -ForegroundColor White
|
||||
Write-Host " ✓ Resolved the conflict by keeping both changes" -ForegroundColor White
|
||||
Write-Host " ✓ Completed the merge" -ForegroundColor White
|
||||
Write-Host "`nYou're now ready to handle merge conflicts in real projects!" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
exit 0
|
||||
} else {
|
||||
Write-Host "[SUMMARY] Some checks failed. Review the hints above." -ForegroundColor Red
|
||||
Write-Host ""
|
||||
Write-Host "Quick guide:" -ForegroundColor Cyan
|
||||
Write-Host " 1. Make sure you're on main: git switch main" -ForegroundColor White
|
||||
Write-Host " 2. Merge first branch: git merge add-timeout" -ForegroundColor White
|
||||
Write-Host " 3. Merge second branch: git merge add-debug" -ForegroundColor White
|
||||
Write-Host " 4. Resolve conflict: edit config.json, remove markers, keep both settings" -ForegroundColor White
|
||||
Write-Host " 5. Stage resolved file: git add config.json" -ForegroundColor White
|
||||
Write-Host " 6. Complete merge: git commit" -ForegroundColor White
|
||||
Write-Host " 7. Run this verify script again" -ForegroundColor White
|
||||
Write-Host ""
|
||||
exit 1
|
||||
}
|
||||
Reference in New Issue
Block a user