From d87c4524dc2acee609cf8186f73144fbf5e0e882 Mon Sep 17 00:00:00 2001 From: Bjarke Sporring Date: Sun, 4 Jan 2026 16:43:21 +0100 Subject: [PATCH] feat: initial module 3 --- README.md | 43 ++++++++++---- module-03-branching/README.md | 94 +++++++++++++++++++++++++++++ module-03-branching/reset.ps1 | 26 ++++++++ module-03-branching/setup.ps1 | 85 ++++++++++++++++++++++++++ module-03-branching/verify.ps1 | 105 +++++++++++++++++++++++++++++++++ 5 files changed, 342 insertions(+), 11 deletions(-) create mode 100644 module-03-branching/README.md create mode 100644 module-03-branching/reset.ps1 create mode 100644 module-03-branching/setup.ps1 create mode 100644 module-03-branching/verify.ps1 diff --git a/README.md b/README.md index df05e60..2e0f77a 100644 --- a/README.md +++ b/README.md @@ -7,17 +7,16 @@ A hands-on, progressive git workshop with practical challenges ranging from basi Each module is a self-contained challenge that teaches specific git concepts: - **Module 01**: Git Basics (init, add, commit, status) -- **Module 02**: Understanding the Staging Area -- **Module 03**: Viewing History (log, diff) -- **Module 04**: Branching Basics -- **Module 05**: Merging -- **Module 06**: Merge Conflicts -- **Module 07**: Rebasing -- **Module 08**: Interactive Rebase -- **Module 09**: Cherry-pick -- **Module 10**: Reset vs Revert -- **Module 11**: Stash -- **Module 12**: Working with Remotes +- **Module 02**: Viewing History (log, diff) +- **Module 03**: Branching Basics +- **Module 04**: Merging +- **Module 05**: Merge Conflicts +- **Module 06**: Rebasing +- **Module 07**: Interactive Rebase +- **Module 08**: Cherry-pick +- **Module 09**: Reset vs Revert +- **Module 10**: Stash +- **Module 11**: Working with Remotes ## How to Use This Workshop @@ -34,6 +33,28 @@ Each module is a self-contained challenge that teaches specific git concepts: - PowerShell (Windows PowerShell 5.1+ or PowerShell Core 7+) - Basic command line knowledge +## Optional: Install Glow for Pretty Markdown + +This workshop includes many markdown files with instructions. You can install `glow` to render them beautifully in your terminal: + +```powershell +.\install-glow.ps1 +``` + +After installation, read markdown files with: + +```powershell +# Windows +.\bin\glow.exe README.md + +# macOS/Linux +./bin/glow README.md +``` + +**Pro tip**: Use `glow -p` for pager mode on longer files! + +Without glow, you can still read markdown files with any text editor or `cat README.md`. + ## Getting Started Start with Module 01: diff --git a/module-03-branching/README.md b/module-03-branching/README.md new file mode 100644 index 0000000..e504fac --- /dev/null +++ b/module-03-branching/README.md @@ -0,0 +1,94 @@ +# Module 03: Branching Basics + +## Learning Objectives + +In this module, you will: +- Understand what a branch is in Git +- Create new branches using `git branch` or `git checkout -b` +- Switch between branches using `git checkout` or `git switch` +- View all branches with `git branch` +- Understand that branches allow parallel development + +## Challenge + +### Setup + +Run the setup script to create your challenge environment: + +```powershell +.\setup.ps1 +``` + +This will create a `challenge/` directory with a Git repository that has some initial commits on the main branch. + +### Your Task + +Your goal is to create a feature branch, make commits on it, and understand how branches work independently. + +**Steps:** + +1. Create a new branch called `feature-login` +2. Switch to the new branch +3. Create a new file `login.py` with some login functionality +4. Commit the new file to your feature branch +5. Make another change to `login.py` and commit it +6. Switch back to the main branch and observe that `login.py` doesn't exist there + +**Suggested Approach:** + +1. Navigate to the challenge directory: `cd challenge` +2. View existing branches: `git branch` +3. Create and switch to new branch: `git checkout -b feature-login` +4. Create `login.py` with any content you like +5. Stage and commit: `git add login.py` and `git commit -m "Add login functionality"` +6. Modify `login.py`, then commit again +7. Switch back to main: `git checkout main` +8. Run `ls` and notice that `login.py` doesn't exist on main! +9. Switch back to feature-login: `git checkout feature-login` +10. Run `ls` again and see that `login.py` is back! + +> **Important Notes:** +> - You can use either `git checkout` or `git switch` to change branches +> - `git checkout -b ` creates and switches in one command +> - `git switch -c ` is the newer equivalent +> - Branches are independent - files in one branch don't affect another until you merge +> - You can switch between branches as many times as you want + +## Key Concepts + +- **Branch**: A lightweight movable pointer to a commit. Branches allow you to work on different features independently. +- **HEAD**: A pointer to the current branch you're working on. When you switch branches, HEAD moves. +- **main/master**: The default branch name in Git (main is the modern convention, master is older). +- **Feature Branch**: A branch created to develop a specific feature, separate from the main codebase. + +## Useful Commands + +```bash +git branch # List all branches (* shows current) +git branch # Create a new branch +git checkout # Switch to an existing branch +git checkout -b # Create and switch to new branch +git switch # Switch to a branch (newer syntax) +git switch -c # Create and switch (newer syntax) +git branch -d # Delete a branch (we won't use this yet) +``` + +## Verification + +Once you've completed the challenge, verify your solution: + +```powershell +.\verify.ps1 +``` + +The verification script will check that you've created the branch, made commits, and that the branches are independent. + +## Need to Start Over? + +If you want to reset the challenge and start fresh: + +```powershell +.\reset.ps1 +``` + +This will remove the challenge directory and run the setup script again, giving you a clean slate. diff --git a/module-03-branching/reset.ps1 b/module-03-branching/reset.ps1 new file mode 100644 index 0000000..cd38f66 --- /dev/null +++ b/module-03-branching/reset.ps1 @@ -0,0 +1,26 @@ +#!/usr/bin/env pwsh +<# +.SYNOPSIS + Resets the Module 03 challenge environment. + +.DESCRIPTION + This script removes the existing challenge directory and runs + the setup script again to create a fresh challenge environment. +#> + +Write-Host "`n=== Resetting Module 03 Challenge ===" -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" +} else { + Write-Host "No existing challenge directory found." -ForegroundColor Cyan +} + +Write-Host "" +Write-Host "----------------------------------------" -ForegroundColor Cyan +Write-Host "" + +# Run setup script +& "$PSScriptRoot\setup.ps1" diff --git a/module-03-branching/setup.ps1 b/module-03-branching/setup.ps1 new file mode 100644 index 0000000..2a4c88b --- /dev/null +++ b/module-03-branching/setup.ps1 @@ -0,0 +1,85 @@ +#!/usr/bin/env pwsh +<# +.SYNOPSIS + Sets up the Module 03 challenge environment for learning about branches. + +.DESCRIPTION + This script creates a challenge directory with a Git repository that + contains a couple of commits on the main branch. Students will create + a feature branch and make commits on it. +#> + +Write-Host "`n=== Setting up Module 03 Challenge ===" -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" + +# Commit 1: Initial commit +Write-Host "Creating initial project..." -ForegroundColor Green +$mainContent = @" +# main.py - Main application file + +def main(): + print("Welcome to the Application!") + print("This is the main branch") + +if __name__ == "__main__": + main() +"@ +Set-Content -Path "main.py" -Value $mainContent + +git add . +git commit -m "Initial commit" | Out-Null + +# Commit 2: Add main functionality +Write-Host "Adding main functionality..." -ForegroundColor Green +$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 + +# 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 "`nNext steps:" -ForegroundColor Cyan +Write-Host " 1. cd challenge" -ForegroundColor White +Write-Host " 2. Create a new branch: git checkout -b feature-login" -ForegroundColor White +Write-Host " 3. Create login.py and commit it" -ForegroundColor White +Write-Host " 4. Make another commit on the feature branch" -ForegroundColor White +Write-Host " 5. Switch back to main: git checkout main" -ForegroundColor White +Write-Host " 6. Observe that login.py doesn't exist on main!" -ForegroundColor White +Write-Host " 7. Run '..\verify.ps1' to check your solution" -ForegroundColor White +Write-Host "" diff --git a/module-03-branching/verify.ps1 b/module-03-branching/verify.ps1 new file mode 100644 index 0000000..eebc44c --- /dev/null +++ b/module-03-branching/verify.ps1 @@ -0,0 +1,105 @@ +#!/usr/bin/env pwsh +<# +.SYNOPSIS + Verifies the Module 03 challenge solution. + +.DESCRIPTION + This script checks that: + - The challenge directory exists + - A Git repository exists + - The feature-login branch exists + - The branch has at least 2 new commits + - login.py exists in the feature branch but not in main +#> + +Write-Host "`n=== Verifying Module 03 Solution ===" -ForegroundColor Cyan + +$allChecksPassed = $true + +# Check if challenge directory exists +if (-not (Test-Path "challenge")) { + Write-Host "[FAIL] Challenge directory not found. Did you run setup.ps1?" -ForegroundColor Red + exit 1 +} + +Set-Location "challenge" + +# Check if git repository exists +if (-not (Test-Path ".git")) { + Write-Host "[FAIL] Not a git repository. Did you run setup.ps1?" -ForegroundColor Red + Set-Location .. + exit 1 +} + +# 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-Host "[PASS] Branch 'feature-login' exists" -ForegroundColor Green +} else { + Write-Host "[FAIL] Branch 'feature-login' not found" -ForegroundColor Red + Write-Host "[HINT] Create the branch with: git checkout -b feature-login" -ForegroundColor Yellow + $allChecksPassed = $false + Set-Location .. + exit 1 +} + +# Check if feature-login has commits beyond main +$commitCount = git rev-list main..feature-login --count 2>$null +if ($commitCount -ge 2) { + Write-Host "[PASS] Branch 'feature-login' has $commitCount new commits" -ForegroundColor Green +} else { + Write-Host "[FAIL] Branch 'feature-login' needs at least 2 new commits (found: $commitCount)" -ForegroundColor Red + Write-Host "[HINT] Make sure you've committed login.py and made at least one more commit" -ForegroundColor Yellow + $allChecksPassed = $false +} + +# Switch to feature-login and check for login.py +git checkout feature-login 2>$null | Out-Null +if (Test-Path "login.py") { + Write-Host "[PASS] File 'login.py' exists in feature-login branch" -ForegroundColor Green +} else { + Write-Host "[FAIL] File 'login.py' not found in feature-login branch" -ForegroundColor Red + Write-Host "[HINT] Create login.py and commit it to the feature-login branch" -ForegroundColor Yellow + $allChecksPassed = $false +} + +# Switch to main and verify login.py doesn't exist +git checkout main 2>$null | Out-Null +if (-not (Test-Path "login.py")) { + Write-Host "[PASS] File 'login.py' does NOT exist in main branch (branches are independent!)" -ForegroundColor Green +} else { + Write-Host "[FAIL] File 'login.py' should not exist in main branch" -ForegroundColor Red + Write-Host "[HINT] Make sure you created login.py only on the feature-login branch" -ForegroundColor Yellow + $allChecksPassed = $false +} + +# Switch back to original branch +if ($originalBranch) { + git checkout $originalBranch 2>$null | Out-Null +} + +Set-Location .. + +# Final summary +if ($allChecksPassed) { + Write-Host "`n" -NoNewline + Write-Host "=====================================" -ForegroundColor Green + Write-Host " CONGRATULATIONS! CHALLENGE PASSED!" -ForegroundColor Green + Write-Host "=====================================" -ForegroundColor Green + Write-Host "`nYou've successfully learned about Git branches!" -ForegroundColor Cyan + Write-Host "You now understand:" -ForegroundColor Cyan + Write-Host " - How to create branches with git checkout -b" -ForegroundColor White + Write-Host " - How to switch between branches" -ForegroundColor White + Write-Host " - That branches are independent lines of development" -ForegroundColor White + Write-Host " - That files in one branch don't affect another" -ForegroundColor White + Write-Host "`nReady for the next module!" -ForegroundColor Green + Write-Host "" +} else { + Write-Host "`n[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 "" + exit 1 +}