385 lines
9.3 KiB
Markdown
385 lines
9.3 KiB
Markdown
# Module 07: Git Stash - Temporary Storage
|
|
|
|
## Learning Objectives
|
|
|
|
By the end of this module, you will:
|
|
- Understand what git stash is and when to use it
|
|
- Temporarily save work without committing
|
|
- Switch between branches without losing uncommitted changes
|
|
- Manage multiple stashes
|
|
- Apply and remove stashed changes
|
|
- Understand the difference between stash pop and stash apply
|
|
|
|
## Challenge Description
|
|
|
|
You're working on a feature when your teammate reports a critical bug in production. You need to switch to the main branch to fix it immediately, but your current work is incomplete and not ready to commit.
|
|
|
|
Your task is to:
|
|
1. Stash your incomplete work
|
|
2. Switch to the main branch
|
|
3. Fix the urgent bug and commit it
|
|
4. Return to your feature branch
|
|
5. Restore your stashed changes
|
|
6. Complete your feature and commit it
|
|
|
|
## Key Concepts
|
|
|
|
### What is Git Stash?
|
|
|
|
Git stash temporarily saves your uncommitted changes (both staged and unstaged) and reverts your working directory to match the HEAD commit. Think of it as a clipboard for your changes.
|
|
|
|
### When to Use Stash
|
|
|
|
Use stash when you need to:
|
|
- Switch branches but have uncommitted changes
|
|
- Pull updates from remote but have local modifications
|
|
- Quickly test something on a clean working directory
|
|
- Save work temporarily without creating a commit
|
|
- Context-switch between tasks
|
|
|
|
### Stash vs Commit
|
|
|
|
**Stash:**
|
|
- Temporary storage
|
|
- Not part of project history
|
|
- Can be applied to different branches
|
|
- Easy to discard if not needed
|
|
- Local only (not pushed to remote)
|
|
|
|
**Commit:**
|
|
- Permanent part of history
|
|
- Creates a snapshot in the project timeline
|
|
- Associated with a specific branch
|
|
- Should be meaningful and complete
|
|
- Can be pushed to remote
|
|
|
|
### The Stash Stack
|
|
|
|
Git stash works like a stack (LIFO - Last In, First Out):
|
|
```
|
|
stash@{0} <- Most recent stash (top of stack)
|
|
stash@{1}
|
|
stash@{2} <- Oldest stash
|
|
```
|
|
|
|
You can have multiple stashes and apply any of them.
|
|
|
|
## Setup
|
|
|
|
Run the setup script to create the challenge environment:
|
|
|
|
```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 push -m "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 push -m "description"
|
|
|
|
# Stash without a message (not recommended)
|
|
git stash
|
|
|
|
# Stash including untracked files
|
|
git stash -u
|
|
|
|
# List all stashes
|
|
git stash list
|
|
|
|
# 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
|
|
|
|
# Apply most recent stash but keep it in stack
|
|
git stash apply
|
|
|
|
# Apply a specific stash
|
|
git stash apply "stash@{1}"
|
|
```
|
|
|
|
### Managing Stashes
|
|
|
|
```pwsh
|
|
# Drop (delete) the most recent stash
|
|
git stash drop
|
|
|
|
# Drop a specific stash
|
|
git stash drop "stash@{1}"
|
|
|
|
# Clear all stashes
|
|
git stash clear
|
|
|
|
# Create a new branch from a stash
|
|
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
|
|
|
|
Run the verification script to check your solution:
|
|
|
|
```pwsh
|
|
..\verify.ps1
|
|
```
|
|
|
|
Or from the module directory:
|
|
|
|
```pwsh
|
|
.\verify.ps1
|
|
```
|
|
|
|
The verification will check that:
|
|
- ✅ The bug fix commit exists on main
|
|
- ✅ Your feature is completed on the feature-login branch
|
|
- ✅ All TODOs are removed from login.py
|
|
- ✅ No uncommitted changes remain
|
|
|
|
## Troubleshooting
|
|
|
|
### "Cannot switch branches - you have uncommitted changes"
|
|
|
|
**Problem:** Git won't let you switch branches with uncommitted changes.
|
|
|
|
**Solution:**
|
|
```pwsh
|
|
# Stash your changes first
|
|
git stash push -m "work in progress"
|
|
|
|
# Now you can switch
|
|
git switch other-branch
|
|
|
|
# When you come back, restore your work
|
|
git switch original-branch
|
|
git stash pop
|
|
```
|
|
|
|
### "I don't remember what's in my stash"
|
|
|
|
**Problem:** You stashed something but forgot what it was.
|
|
|
|
**Solution:**
|
|
```pwsh
|
|
# 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}"
|
|
```
|
|
|
|
### "Stash conflicts when I apply"
|
|
|
|
**Problem:** Applying a stash causes merge conflicts.
|
|
|
|
**Solution:**
|
|
1. Git marks conflicts in your files with `<<<<<<<` markers
|
|
2. Open the files and resolve conflicts manually
|
|
3. Stage the resolved files: `git add <file>`
|
|
4. If you used `pop`, the stash is automatically dropped
|
|
5. If you used `apply`, manually drop it: `git stash drop`
|
|
|
|
### "I accidentally cleared my stash"
|
|
|
|
**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 push -m "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 push -m "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 push -m "local changes"
|
|
git pull
|
|
git stash pop
|
|
# Resolve conflicts if any
|
|
```
|
|
|
|
### Test Clean State
|
|
```pwsh
|
|
# Stash changes to test on clean code
|
|
git stash push -m "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
|
|
```
|