feat: initial module 02
This commit is contained in:
88
module-02-history/README.md
Normal file
88
module-02-history/README.md
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# Module 02: Viewing History
|
||||||
|
|
||||||
|
## Learning Objectives
|
||||||
|
|
||||||
|
In this module, you will:
|
||||||
|
- Understand commit history and how to navigate it
|
||||||
|
- Use `git log` to view commit history with various formats
|
||||||
|
- Use `git show` to view specific commit details
|
||||||
|
- Use `git diff` to compare changes between commits
|
||||||
|
- Understand commit hashes and references
|
||||||
|
|
||||||
|
## 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 already has some commit history.
|
||||||
|
|
||||||
|
### Your Task
|
||||||
|
|
||||||
|
You'll explore an existing Git repository that contains multiple commits. Your goal is to use Git commands to discover information about the repository's history and answer the following questions:
|
||||||
|
|
||||||
|
1. **How many commits are in the repository?**
|
||||||
|
2. **What was the commit message for the third commit?** (counting from the first/oldest commit)
|
||||||
|
3. **Which file was modified in the "Fix authentication bug" commit?**
|
||||||
|
4. **What changes were made to app.py between the first and last commits?** (briefly describe)
|
||||||
|
|
||||||
|
Create a file called `answers.txt` in the challenge directory with your answers. You can format your answers however you like, as long as the information is there.
|
||||||
|
|
||||||
|
**Suggested Approach:**
|
||||||
|
|
||||||
|
1. Navigate to the challenge directory: `cd challenge`
|
||||||
|
2. View the commit history: `git log`
|
||||||
|
3. Try different log formats: `git log --oneline`, `git log --stat`
|
||||||
|
4. View specific commits: `git show <commit-hash>`
|
||||||
|
5. Compare commits: `git diff <commit1> <commit2>`
|
||||||
|
6. Create `answers.txt` with your findings
|
||||||
|
|
||||||
|
> **Important Notes:**
|
||||||
|
> - You can use any Git commands you like to explore the repository
|
||||||
|
> - The format of your answers is flexible - just make sure the information is clear
|
||||||
|
> - Try different `git log` options to see which format you prefer
|
||||||
|
> - Commit hashes can be referenced by their full hash or just the first 7 characters
|
||||||
|
|
||||||
|
## Key Concepts
|
||||||
|
|
||||||
|
- **Commit Hash**: A unique identifier (SHA-1 hash) for each commit. You can use the full hash or just the first few characters.
|
||||||
|
- **Commit Message**: A description of what changed in that commit, written by the author.
|
||||||
|
- **Commit History**: The chronological record of all changes made to a repository.
|
||||||
|
- **HEAD**: A pointer to the current commit you're working from.
|
||||||
|
|
||||||
|
## Useful Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git log # View commit history
|
||||||
|
git log --oneline # Compact one-line format
|
||||||
|
git log --stat # Show files changed in each commit
|
||||||
|
git log --graph # Show branch graph (more useful with branches)
|
||||||
|
git show <commit> # View specific commit details
|
||||||
|
git show <commit>:<file> # View a file from a specific commit
|
||||||
|
git diff <commit1> <commit2> # Compare two commits
|
||||||
|
git diff <commit> # Compare commit with current working directory
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
Once you've created your `answers.txt` file, verify your solution:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\verify.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
The verification script will check that your answers contain the expected information.
|
||||||
|
|
||||||
|
## 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.
|
||||||
26
module-02-history/reset.ps1
Normal file
26
module-02-history/reset.ps1
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/env pwsh
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Resets the Module 02 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 02 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"
|
||||||
207
module-02-history/setup.ps1
Normal file
207
module-02-history/setup.ps1
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
#!/usr/bin/env pwsh
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Sets up the Module 02 challenge environment with commit history.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
This script creates a challenge directory with a Git repository that
|
||||||
|
contains multiple commits for students to explore using git log and git diff.
|
||||||
|
#>
|
||||||
|
|
||||||
|
Write-Host "`n=== Setting up Module 02 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 project structure
|
||||||
|
Write-Host "Creating initial project structure..." -ForegroundColor Green
|
||||||
|
$readmeContent = @"
|
||||||
|
# My App
|
||||||
|
|
||||||
|
This is a simple web application built with Python.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- User authentication
|
||||||
|
- Database integration
|
||||||
|
- User profiles
|
||||||
|
"@
|
||||||
|
Set-Content -Path "README.md" -Value $readmeContent
|
||||||
|
|
||||||
|
$appContent = @"
|
||||||
|
# app.py - Main application file
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("Welcome to My App!")
|
||||||
|
# Application initialization code here
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
"@
|
||||||
|
Set-Content -Path "app.py" -Value $appContent
|
||||||
|
|
||||||
|
git add .
|
||||||
|
git commit -m "Initial project structure" | Out-Null
|
||||||
|
|
||||||
|
# Commit 2: Add user authentication
|
||||||
|
Write-Host "Adding user authentication..." -ForegroundColor Green
|
||||||
|
$authContent = @"
|
||||||
|
# auth.py - Authentication module
|
||||||
|
|
||||||
|
def login(username, password):
|
||||||
|
# Authenticate user
|
||||||
|
print(f"Logging in user: {username}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
def logout(username):
|
||||||
|
# Log out user
|
||||||
|
print(f"Logging out user: {username}")
|
||||||
|
return True
|
||||||
|
"@
|
||||||
|
Set-Content -Path "auth.py" -Value $authContent
|
||||||
|
|
||||||
|
$appContent = @"
|
||||||
|
# app.py - Main application file
|
||||||
|
from auth import login, logout
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("Welcome to My App!")
|
||||||
|
# Application initialization code here
|
||||||
|
login("user", "password")
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
"@
|
||||||
|
Set-Content -Path "app.py" -Value $appContent
|
||||||
|
|
||||||
|
git add .
|
||||||
|
git commit -m "Add user authentication" | Out-Null
|
||||||
|
|
||||||
|
# Commit 3: Add database connection
|
||||||
|
Write-Host "Adding database connection..." -ForegroundColor Green
|
||||||
|
$databaseContent = @"
|
||||||
|
# database.py - Database connection module
|
||||||
|
|
||||||
|
def connect():
|
||||||
|
# Connect to database
|
||||||
|
print("Connecting to database...")
|
||||||
|
return True
|
||||||
|
|
||||||
|
def disconnect():
|
||||||
|
# Disconnect from database
|
||||||
|
print("Disconnecting from database...")
|
||||||
|
return True
|
||||||
|
"@
|
||||||
|
Set-Content -Path "database.py" -Value $databaseContent
|
||||||
|
|
||||||
|
$appContent = @"
|
||||||
|
# app.py - Main application file
|
||||||
|
from auth import login, logout
|
||||||
|
from database import connect, disconnect
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("Welcome to My App!")
|
||||||
|
connect()
|
||||||
|
# Application initialization code here
|
||||||
|
login("user", "password")
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
"@
|
||||||
|
Set-Content -Path "app.py" -Value $appContent
|
||||||
|
|
||||||
|
git add .
|
||||||
|
git commit -m "Add database connection" | Out-Null
|
||||||
|
|
||||||
|
# Commit 4: Fix authentication bug
|
||||||
|
Write-Host "Fixing authentication bug..." -ForegroundColor Green
|
||||||
|
$authContent = @"
|
||||||
|
# auth.py - Authentication module
|
||||||
|
|
||||||
|
def login(username, password):
|
||||||
|
# Authenticate user
|
||||||
|
if not username or not password:
|
||||||
|
print("Error: Username and password required")
|
||||||
|
return False
|
||||||
|
print(f"Logging in user: {username}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
def logout(username):
|
||||||
|
# Log out user
|
||||||
|
print(f"Logging out user: {username}")
|
||||||
|
return True
|
||||||
|
"@
|
||||||
|
Set-Content -Path "auth.py" -Value $authContent
|
||||||
|
|
||||||
|
git add .
|
||||||
|
git commit -m "Fix authentication bug" | Out-Null
|
||||||
|
|
||||||
|
# Commit 5: Add user profile feature
|
||||||
|
Write-Host "Adding user profile feature..." -ForegroundColor Green
|
||||||
|
$profileContent = @"
|
||||||
|
# profile.py - User profile module
|
||||||
|
|
||||||
|
def get_profile(username):
|
||||||
|
# Get user profile
|
||||||
|
print(f"Fetching profile for: {username}")
|
||||||
|
return {"username": username, "email": f"{username}@example.com"}
|
||||||
|
|
||||||
|
def update_profile(username, data):
|
||||||
|
# Update user profile
|
||||||
|
print(f"Updating profile for: {username}")
|
||||||
|
return True
|
||||||
|
"@
|
||||||
|
Set-Content -Path "profile.py" -Value $profileContent
|
||||||
|
|
||||||
|
$appContent = @"
|
||||||
|
# app.py - Main application file
|
||||||
|
from auth import login, logout
|
||||||
|
from database import connect, disconnect
|
||||||
|
from profile import get_profile
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("Welcome to My App!")
|
||||||
|
connect()
|
||||||
|
# Application initialization code here
|
||||||
|
if login("user", "password"):
|
||||||
|
profile = get_profile("user")
|
||||||
|
print(f"User profile: {profile}")
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
"@
|
||||||
|
Set-Content -Path "app.py" -Value $appContent
|
||||||
|
|
||||||
|
git add .
|
||||||
|
git commit -m "Add user profile feature" | 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. Explore the commit history using 'git log'" -ForegroundColor White
|
||||||
|
Write-Host " 3. Answer the questions in README.md by creating 'answers.txt'" -ForegroundColor White
|
||||||
|
Write-Host " 4. Run '..\verify.ps1' to check your answers" -ForegroundColor White
|
||||||
|
Write-Host ""
|
||||||
102
module-02-history/verify.ps1
Normal file
102
module-02-history/verify.ps1
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
#!/usr/bin/env pwsh
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Verifies the Module 02 challenge solution.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
This script checks that:
|
||||||
|
- The challenge directory exists
|
||||||
|
- A Git repository exists
|
||||||
|
- answers.txt exists with correct information about commit history
|
||||||
|
#>
|
||||||
|
|
||||||
|
Write-Host "`n=== Verifying Module 02 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
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if answers.txt exists
|
||||||
|
if (-not (Test-Path "answers.txt")) {
|
||||||
|
Write-Host "[FAIL] answers.txt not found. Create this file with your answers." -ForegroundColor Red
|
||||||
|
Write-Host "[HINT] Review the questions in README.md and create answers.txt" -ForegroundColor Yellow
|
||||||
|
$allChecksPassed = $false
|
||||||
|
} else {
|
||||||
|
Write-Host "[PASS] answers.txt exists" -ForegroundColor Green
|
||||||
|
|
||||||
|
# Read the answers file
|
||||||
|
$answers = Get-Content "answers.txt" -Raw
|
||||||
|
$answersLower = $answers.ToLower()
|
||||||
|
|
||||||
|
# Check 1: Contains "5" or "five" for commit count
|
||||||
|
if ($answersLower -match "5|five") {
|
||||||
|
Write-Host "[PASS] Correct commit count found" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host "[FAIL] Commit count not found or incorrect" -ForegroundColor Red
|
||||||
|
Write-Host "[HINT] Use 'git log --oneline' to count commits easily" -ForegroundColor Yellow
|
||||||
|
$allChecksPassed = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check 2: Contains "database" keyword for third commit
|
||||||
|
if ($answersLower -match "database") {
|
||||||
|
Write-Host "[PASS] Third commit message identified" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host "[FAIL] Third commit message not found" -ForegroundColor Red
|
||||||
|
Write-Host "[HINT] Use 'git log' to see commit messages in order" -ForegroundColor Yellow
|
||||||
|
$allChecksPassed = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check 3: Contains "auth" keyword for file modified in bug fix
|
||||||
|
if ($answersLower -match "auth") {
|
||||||
|
Write-Host "[PASS] Correct file identified for bug fix commit" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host "[FAIL] File modified in bug fix commit not found" -ForegroundColor Red
|
||||||
|
Write-Host "[HINT] Use 'git log --stat' to see which files were changed in each commit" -ForegroundColor Yellow
|
||||||
|
$allChecksPassed = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check 4: Some mention of changes (flexible check)
|
||||||
|
if ($answersLower -match "import|profile|function|added|login|connect") {
|
||||||
|
Write-Host "[PASS] Changes to app.py described" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host "[FAIL] Changes to app.py not described" -ForegroundColor Red
|
||||||
|
Write-Host "[HINT] Use 'git diff <first-commit> <last-commit> app.py' to see changes" -ForegroundColor Yellow
|
||||||
|
$allChecksPassed = $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 explored Git commit history!" -ForegroundColor Cyan
|
||||||
|
Write-Host "You now know how to:" -ForegroundColor Cyan
|
||||||
|
Write-Host " - View commit history with git log" -ForegroundColor White
|
||||||
|
Write-Host " - Find specific commits and their messages" -ForegroundColor White
|
||||||
|
Write-Host " - See which files changed in commits" -ForegroundColor White
|
||||||
|
Write-Host " - Compare changes between commits with git diff" -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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user