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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user