Stashing Changes
Stashing is one of Git's most useful features for managing work-in-progress. It allows you to temporarily save uncommitted changes (both staged and unstaged) and return to a clean working directory. This is invaluable when you need to quickly switch contexts without committing incomplete work.
Understanding Git Stash
Think of the stash as a clipboard for your work:
What is Stashing?
- Temporarily stores modified tracked files
- Saves both staged and unstaged changes
- Returns working directory to last commit state
- Allows you to switch branches or pull updates
- Changes can be reapplied later
- Stash is local (never pushed to remote)
When to Use Stash: You're working on a feature but need to urgently fix a bug, your manager asks for a quick demo of another branch, or you need to pull updates but have uncommitted work.
Creating a Stash
The basic command to stash your changes:
# Stash all modified tracked files
git stash
# Stash with a descriptive message
git stash save "WIP: user authentication feature"
# Modern syntax (Git 2.13+)
git stash push -m "WIP: working on login form"
# Stash only specific files
git stash push -m "Config changes" config.php database.php
After stashing, your working directory is clean and matches the last commit.
Note: git stash is shorthand for git stash push. Both commands do the same thing.
What Gets Stashed?
Understanding what stash includes and excludes:
✓ Included by default:
- Modified tracked files (in working directory)
- Staged changes (added with git add)
✗ Not included by default:
- Untracked files (new files not added)
- Ignored files (.gitignore)
Include untracked files:
git stash -u
git stash --include-untracked
Include everything (even ignored files):
git stash -a
git stash --all
Warning: git stash --all includes .gitignore files. Be careful not to stash large build artifacts or dependencies. Use -u for untracked files only.
Viewing Your Stashes
Git maintains a stack of stashes - you can have multiple stashes saved:
# List all stashes
git stash list
# Output example:
stash@{0}: WIP on main: abc1234 Add user login
stash@{1}: WIP on feature: def5678 Update database schema
stash@{2}: On main: ghi9012 Emergency bug fix prep
# View stash contents
git stash show
# View detailed diff of a stash
git stash show -p
git stash show -p stash@{1}
# View specific stash
git show stash@{0}
Applying Stashed Changes
You have two ways to restore stashed changes:
Apply (keeps stash in list):
git stash apply # Apply most recent stash
git stash apply stash@{1} # Apply specific stash
Pop (removes from list):
git stash pop # Apply and remove most recent
git stash pop stash@{1} # Apply and remove specific stash
The difference between apply and pop:
git stash apply:
- Applies changes to working directory
- Keeps stash in the stash list
- Use when you might need stash again
- Safer option
git stash pop:
- Applies changes to working directory
- Removes stash from the list
- Use when you're done with the stash
- Cleaner stash list
Best Practice: Use git stash pop when you're sure you won't need the stash again. Use git stash apply if you want to try applying it without losing it.
Handling Stash Conflicts
Sometimes applying a stash causes conflicts:
# Try to apply stash
git stash pop
# If conflicts occur:
Auto-merging index.php
CONFLICT (content): Merge conflict in index.php
# Resolve conflicts manually
# Edit index.php to fix conflicts
# Then:
git add index.php
# Stash pop was interrupted, so drop it manually
git stash drop
Note: When git stash pop encounters conflicts, it doesn't automatically remove the stash. You must use git stash drop after resolving conflicts.
Creating a Branch from Stash
Sometimes you realize stashed work should be a new branch:
# Create new branch and apply stash in one command
git stash branch new-feature-branch
# Create branch from specific stash
git stash branch bug-fix stash@{2}
# This is equivalent to:
git checkout -b new-feature-branch
git stash pop
This is particularly useful when:
- Your stashed changes conflict with current branch
- You realize the work should be isolated
- You want a clean starting point for the stashed work
Managing Your Stash Stack
Commands for cleaning up and organizing stashes:
# Drop specific stash
git stash drop stash@{1}
# Drop most recent stash
git stash drop
# Clear all stashes (be careful!)
git stash clear
# Rename not possible, but you can:
# 1. Apply the stash
# 2. Drop it
# 3. Create new stash with better name
git stash apply stash@{2}
git stash drop stash@{2}
git stash save "Better description of changes"
Warning: git stash clear permanently deletes ALL stashes. This cannot be undone. Use with extreme caution!
Partial Stashing
Stash only part of your changes with interactive mode:
# Interactively select what to stash
git stash -p
git stash --patch
# For each change, you'll be asked:
Stash this hunk [y,n,q,a,d,e,?]?
y - stash this hunk
n - don't stash this hunk
q - quit (don't stash remaining hunks)
a - stash this and all remaining hunks
d - don't stash this or remaining hunks
e - manually edit the hunk
? - help
Practical Stash Workflows
Common scenarios where stashing shines:
Scenario 1: Emergency Bug Fix
# You're coding a feature when a critical bug is reported
git stash save "WIP: feature half done"
git checkout main
git checkout -b hotfix
# Fix the bug, commit, merge
git checkout feature-branch
git stash pop
Scenario 2: Pull Updates
# You have uncommitted work and need to pull
git stash
git pull origin main
git stash pop
# Resolve any conflicts
Scenario 3: Experiment Safely
# Try something without committing
git stash save "Current stable state"
# Make experimental changes
# If it works: commit
# If it fails: git stash pop (restore previous state)
Scenario 4: Switch Branches
# Need to review a colleague's PR
git stash save "Feature progress"
git checkout colleague-branch
# Review their work
git checkout your-branch
git stash pop
Advanced Stash Techniques
# Stash with staging info preserved
git stash save --keep-index
# Keeps staged changes staged when reapplied
# Stash only unstaged changes
git stash --keep-index
# Apply stash without affecting staging
git stash apply --index
# View stash as a diff
git diff stash@{0}
# Compare stash with current work
git diff stash@{0}..HEAD
Stash Best Practices
✓ DO:
- Use descriptive messages with git stash save
- Regularly clean up old stashes
- Use stash for short-term storage only
- Pop or apply stashes soon after creation
✗ DON'T:
- Use stash as long-term storage (use branches)
- Stash without a message (you'll forget what's in it)
- Accumulate dozens of stashes
- Rely on stash@{0} in scripts (numbers change)
Practice Exercise:
Master stashing workflow:
- Create a new file and modify an existing file
- Stage one change and leave the other unstaged
- Stash all changes with a message
- Verify working directory is clean
- Make a new commit on clean directory
- View your stash list
- Apply the stash and see changes restored
- Create a new stash with untracked files included
- Practice creating a branch from a stash
Commands to try:
echo "new file" > test.txt
echo "changes" >> README.md
git add README.md
git stash save "Testing stash workflow"
git status
git commit -m "Clean state commit"
git stash list
git stash show -p
git stash pop
Troubleshooting Stash Issues
Problem: Stash apply causes conflicts
Solution: Resolve conflicts manually, then git stash drop
Problem: Lost track of what's in a stash
Solution: git stash show -p stash@{N}
Problem: Accidentally cleared all stashes
Solution: Check git reflog for stash commits (advanced)
Problem: Stash not including new files
Solution: Use git stash -u to include untracked files
Problem: Can't pop stash on different branch
Solution: Use git stash branch new-branch-name
Summary
In this lesson, you learned:
- Stashing temporarily saves uncommitted changes without committing
- Use
git stash to save changes and git stash pop to restore
- Stashes are stored in a stack - you can have multiple stashes
- Include untracked files with
-u flag
- Create branches from stashes for better organization
- Use descriptive messages to remember stash contents
- Stash is local and perfect for quick context switching
Next Up: In the next lesson, we'll dive into GitHub - the world's largest code hosting platform and how it extends Git's capabilities!