fix: stash issues

This commit is contained in:
Bjarke Sporring
2026-01-15 16:37:57 +01:00
parent cdd695b250
commit b0d2d43c8b
3 changed files with 283 additions and 87 deletions

View File

@@ -1,4 +1,4 @@
# Module 11: Stash # Module 07: Git Stash - Temporary Storage
## Learning Objectives ## Learning Objectives
@@ -64,12 +64,112 @@ stash@{2} <- Oldest stash
You can have multiple stashes and apply any of them. You can have multiple stashes and apply any of them.
## Useful Commands ## Setup
```bash Run the setup script to create the challenge environment:
# Stash current changes
```pwsh
.\setup.ps1
```
This creates a `challenge/` directory where you're working on a login feature with uncommitted changes, and a critical bug needs fixing on main.
## Your Task
### The Scenario
You're working on a login feature on the `feature-login` branch. Your work is incomplete (has TODOs), so it's not ready to commit.
Suddenly, your teammate reports a **critical security bug** in production! You need to:
1. Temporarily save your incomplete work
2. Switch to the main branch
3. Fix the urgent bug
4. Return to your feature and continue working
### Step-by-Step Instructions
1. **Navigate to the challenge directory:**
```pwsh
cd challenge
```
2. **Check your current status:**
```pwsh
git status
```
You should see modified `login.py` (uncommitted changes)
3. **Stash your work with a message:**
```pwsh
git stash save "WIP: login feature"
```
4. **Verify working directory is clean:**
```pwsh
git status
```
Should say "nothing to commit, working tree clean"
5. **Switch to main branch:**
```pwsh
git switch main
```
6. **Open app.py and find the bug:**
```pwsh
cat app.py
```
Look for the comment "# BUG: This allows unauthenticated access!"
7. **Fix the bug** by editing app.py:
- Remove the buggy comment line
- You can leave the implementation as-is or improve it
- The important thing is removing the comment that says "allows unauthenticated access"
8. **Commit the fix:**
```pwsh
git add app.py
git commit -m "Fix critical security bug"
```
9. **Switch back to your feature branch:**
```pwsh
git switch feature-login
```
10. **Restore your stashed work:**
```pwsh
git stash pop
```
This applies the stash and removes it from the stash stack
11. **Complete the TODOs in login.py:**
- Open login.py in your editor
- Complete the login method (verify password and return session)
- Add a logout method
- Remove all TODO comments
12. **Commit your completed feature:**
```pwsh
git add login.py
git commit -m "Complete login feature"
```
13. **Verify your solution:**
```pwsh
..\verify.ps1
```
## Key Stash Commands
### Basic Operations
```pwsh
# Stash current changes with a message
git stash save "description"
# Stash without a message (not recommended)
git stash git stash
git stash save "description" # With a descriptive message
# Stash including untracked files # Stash including untracked files
git stash -u git stash -u
@@ -77,7 +177,17 @@ git stash -u
# List all stashes # List all stashes
git stash list git stash list
# Apply most recent stash and remove it from stack # Show what's in the most recent stash
git stash show
# Show full diff of stash
git stash show -p
```
### Applying Stashes
```pwsh
# Apply most recent stash and remove it (RECOMMENDED)
git stash pop git stash pop
# Apply most recent stash but keep it in stack # Apply most recent stash but keep it in stack
@@ -86,114 +196,192 @@ git stash apply
# Apply a specific stash # Apply a specific stash
git stash apply stash@{1} git stash apply stash@{1}
# Show what's in a stash # Apply a specific stash by number
git stash show git stash apply 1
git stash show -p # Show full diff ```
# Drop (delete) a stash ### Managing Stashes
git stash drop stash@{0}
```pwsh
# Drop (delete) the most recent stash
git stash drop
# Drop a specific stash
git stash drop stash@{1}
# Clear all stashes # Clear all stashes
git stash clear git stash clear
# Create a branch from a stash # Create a new branch from a stash
git stash branch new-branch-name git stash branch new-branch-name
``` ```
## Understanding Stash vs Pop vs Apply
### Stash Pop (Recommended)
```pwsh
git stash pop
```
- Applies the stash to your working directory
- **Removes** the stash from the stack
- Use this most of the time
### Stash Apply (Keep Stash)
```pwsh
git stash apply
```
- Applies the stash to your working directory
- **Keeps** the stash in the stack
- Useful if you want to apply the same changes to multiple branches
### When to Use Which
**Use `pop` when:**
- You're done with the stash and won't need it again (99% of the time)
- You want to keep your stash list clean
**Use `apply` when:**
- You want to test the same changes on different branches
- You're not sure if you want to keep the stash yet
## Verification ## Verification
Run the verification script to check your solution: Run the verification script to check your solution:
```bash ```pwsh
..\verify.ps1
```
Or from the module directory:
```pwsh
.\verify.ps1 .\verify.ps1
``` ```
The verification will check that: The verification will check that:
- The bug fix commit exists on main - ✅ The bug fix commit exists on main
- Your feature is completed on the feature branch - ✅ Your feature is completed on the feature-login branch
- Changes were properly stashed and restored - ✅ All TODOs are removed from login.py
- No uncommitted changes remain - ✅ No uncommitted changes remain
## Challenge Steps ## Troubleshooting
1. Navigate to the challenge directory ### "Cannot switch branches - you have uncommitted changes"
2. You're on feature-login with uncommitted changes
3. Check status: `git status` (you'll see modified files)
4. Stash your changes: `git stash save "WIP: login feature"`
5. Verify working directory is clean: `git status`
6. Switch to main: `git switch main`
7. View the bug in app.js and fix it (remove the incorrect line)
8. Commit the fix: `git add app.js && git commit -m "Fix critical security bug"`
9. Switch back to feature: `git switch feature-login`
10. Restore your work: `git stash pop`
11. Complete the feature (the TODOs in login.js)
12. Commit your completed feature
13. Run verification
## Tips **Problem:** Git won't let you switch branches with uncommitted changes.
- Always use `git stash save "message"` to describe what you're stashing **Solution:**
- Use `git stash list` to see all your stashes ```pwsh
- `git stash pop` applies and removes the stash (use this most often) # Stash your changes first
- `git stash apply` keeps the stash (useful if you want to apply it to multiple branches) git stash save "work in progress"
- Stashes are local - they don't get pushed to remote repositories
- You can stash even if you have changes to different files
- Stash before pulling to avoid merge conflicts
- Use `git stash show -p` to preview what's in a stash before applying
## Common Stash Scenarios # Now you can switch
git switch other-branch
### Scenario 1: Quick Branch Switch # When you come back, restore your work
```bash git switch original-branch
# Working on feature, need to switch to main
git stash
git switch main
# Do work on main
git switch feature
git stash pop git stash pop
``` ```
### Scenario 2: Pull with Local Changes ### "I don't remember what's in my stash"
```bash
# You have local changes but need to pull **Problem:** You stashed something but forgot what it was.
git stash
git pull **Solution:**
git stash pop ```pwsh
# Resolve any conflicts # List all stashes
git stash list
# Show summary of what changed
git stash show stash@{0}
# Show full diff
git stash show -p stash@{0}
``` ```
### Scenario 3: Experimental Changes ### "Stash conflicts when I apply"
```bash
# Try something experimental
git stash # Save current work
# Make experimental changes
# Decide you don't like it
git restore . # Discard experiment
git stash pop # Restore original work
```
### Scenario 4: Apply to Multiple Branches **Problem:** Applying a stash causes merge conflicts.
```bash
# Same fix needed on multiple branches
git stash
git switch branch1
git stash apply
git commit -am "Apply fix"
git switch branch2
git stash apply
git commit -am "Apply fix"
git stash drop # Clean up when done
```
## Stash Conflicts **Solution:**
1. Git marks conflicts in your files with `<<<<<<<` markers
If applying a stash causes conflicts: 2. Open the files and resolve conflicts manually
1. Git will mark the conflicts in your files
2. Resolve conflicts manually (like merge conflicts)
3. Stage the resolved files: `git add <file>` 3. Stage the resolved files: `git add <file>`
4. The stash is automatically dropped after successful pop 4. If you used `pop`, the stash is automatically dropped
5. If you used `apply`, manually drop it: `git stash drop` 5. If you used `apply`, manually drop it: `git stash drop`
## What You'll Learn ### "I accidentally cleared my stash"
Git stash is an essential tool for managing context switches in your daily workflow. It lets you maintain a clean working directory while preserving incomplete work, making it easy to handle interruptions, urgent fixes, and quick branch switches. Mastering stash makes you more efficient and helps avoid the temptation to make "WIP" commits just to switch branches. Think of stash as your temporary workspace that follows you around. **Problem:** You deleted a stash you still needed.
**Unfortunately:** Stashes are hard to recover once deleted. Lessons learned:
- Use `git stash pop` instead of `git stash drop` when you're unsure
- Use `git stash show -p` to preview before dropping
- Consider committing work instead of stashing for important changes
## Tips for Success
💡 **Always add a message** - `git stash save "your message"` helps you remember what you stashed
💡 **Use pop, not apply** - Pop removes the stash automatically, keeping your stash list clean
💡 **Stash before pulling** - Avoid merge conflicts when pulling updates
💡 **Preview before applying** - Use `git stash show -p` to see what's in a stash
💡 **Stashes are local** - They don't get pushed to remote repositories
💡 **Clean working directory** - Always verify with `git status` after stashing
## Common Use Cases
### Quick Branch Switch
```pwsh
# You're working on feature-A
git stash save "feature A progress"
git switch hotfix-branch
# Fix the issue, commit
git switch feature-A
git stash pop
```
### Pull with Local Changes
```pwsh
# You have uncommitted changes
git stash save "local changes"
git pull
git stash pop
# Resolve conflicts if any
```
### Test Clean State
```pwsh
# Stash changes to test on clean code
git stash save "testing clean state"
# Run tests
git stash pop # Restore your changes
```
## What You've Learned
After completing this module, you understand:
- ✅ Stash temporarily saves uncommitted changes
- ✅ Stash lets you switch contexts without committing
- ✅ `git stash pop` applies and removes the stash
- ✅ `git stash apply` applies but keeps the stash
- ✅ Stashes are local and not pushed to remote
- ✅ Stash is essential for handling interruptions and urgent fixes
**Key Takeaway:** Stash is your "temporary clipboard" for incomplete work. It helps you stay productive when you need to context-switch without making messy "WIP" commits.
## Next Steps
Ready to continue? You've now mastered the essential Git commands for daily development:
- Committing and history
- Branching and merging
- Cherry-picking specific changes
- Safely reverting commits
- Temporarily stashing work
Move on to **Module 08: Multiplayer Git** to practice collaborating with others!
To start over:
```pwsh
.\reset.ps1
```

View File

@@ -158,7 +158,7 @@ Write-Host "`nYour task:" -ForegroundColor Yellow
Write-Host "1. Navigate to the challenge directory: cd challenge" -ForegroundColor White Write-Host "1. Navigate to the challenge directory: cd challenge" -ForegroundColor White
Write-Host "2. Check your status: git status (see uncommitted changes)" -ForegroundColor White Write-Host "2. Check your status: git status (see uncommitted changes)" -ForegroundColor White
Write-Host "3. Stash your work: git stash save 'WIP: login feature'" -ForegroundColor White Write-Host "3. Stash your work: git stash save 'WIP: login feature'" -ForegroundColor White
Write-Host "4. Switch to $mainBranch: git checkout $mainBranch" -ForegroundColor White Write-Host "4. Switch to ${mainBranch}: git checkout $mainBranch" -ForegroundColor White
Write-Host "5. Fix the security bug in app.py (remove the comment and fix the auth)" -ForegroundColor White Write-Host "5. Fix the security bug in app.py (remove the comment and fix the auth)" -ForegroundColor White
Write-Host "6. Commit the fix: git add app.py && git commit -m 'Fix critical security bug'" -ForegroundColor White Write-Host "6. Commit the fix: git add app.py && git commit -m 'Fix critical security bug'" -ForegroundColor White
Write-Host "7. Switch back: git checkout feature-login" -ForegroundColor White Write-Host "7. Switch back: git checkout feature-login" -ForegroundColor White

View File

@@ -73,7 +73,15 @@ git checkout $mainBranch 2>$null | Out-Null
# Check for bug fix commit # Check for bug fix commit
$mainCommits = git log --pretty=format:"%s" $mainBranch 2>$null $mainCommits = git log --pretty=format:"%s" $mainBranch 2>$null
if ($mainCommits -notmatch "security bug|Fix.*bug|security fix") { $hasSecurityFix = $false
foreach ($commit in $mainCommits) {
if ($commit -match "security|Fix.*bug") {
$hasSecurityFix = $true
break
}
}
if (-not $hasSecurityFix) {
Write-Host "[FAIL] No security bug fix commit found on $mainBranch branch." -ForegroundColor Red Write-Host "[FAIL] No security bug fix commit found on $mainBranch branch." -ForegroundColor Red
Write-Host "Hint: After stashing, switch to $mainBranch and commit a bug fix" -ForegroundColor Yellow Write-Host "Hint: After stashing, switch to $mainBranch and commit a bug fix" -ForegroundColor Yellow
git checkout feature-login 2>$null | Out-Null git checkout feature-login 2>$null | Out-Null
@@ -128,7 +136,7 @@ if (-not (Test-Path "login.py")) {
$loginContent = Get-Content "login.py" -Raw $loginContent = Get-Content "login.py" -Raw
# Check that login method exists and is implemented # Check that login method exists and is implemented
if ($loginContent -notmatch "login\(username, password\)") { if ($loginContent -notmatch "def login") {
Write-Host "[FAIL] login.py should have a login method." -ForegroundColor Red Write-Host "[FAIL] login.py should have a login method." -ForegroundColor Red
Set-Location .. Set-Location ..
exit 1 exit 1