Git stash is your safety net when you need to quickly switch contexts without losing work. Whether you're interrupted by an urgent bug fix or need to pull the latest changes, stash lets you temporarily shelve your modifications and return to them later.
Understanding Git Stash
Git stash takes your modified tracked files and staged changes, then saves them on a stack of unfinished changes that you can reapply at any time.
Basic Stash Operations
# Save current changes to stash
git stash
# Or with a descriptive message
git stash save "WIP: Adding user authentication"
# List all stashes
git stash list
# Apply most recent stash
git stash apply
# Apply and remove from stack
git stash pop
Common Stash Scenarios
1. Emergency Context Switch
You're working on a feature when a critical bug report comes in:
# Working on feature
$ git status
modified: src/components/Dashboard.js
modified: src/api/analytics.js
# Critical bug reported! Stash your work
$ git stash save "WIP: Dashboard analytics integration"
# Switch to hotfix
$ git checkout -b hotfix/critical-bug
# Fix the bug...
$ git commit -m "Fix critical payment processing bug"
$ git checkout main
$ git merge hotfix/critical-bug
# Return to your feature
$ git checkout feature/dashboard
$ git stash pop
2. Pulling Latest Changes
Need to update your branch but have uncommitted changes:
# You have local changes
$ git status
modified: package.json
modified: src/index.js
# Can't pull with changes
$ git pull
error: Your local changes would be overwritten
# Stash, pull, then reapply
$ git stash
$ git pull origin main
$ git stash pop
3. Testing Something Quickly
Want to test if your changes are causing an issue:
# Stash current changes
git stash
# Test without your changes
npm test
# Bring changes back
git stash pop
Advanced Stash Techniques
Stashing Specific Files
# Stash only certain files
git stash push -m "Stash only styles" src/styles/*
# Interactive stashing
git stash save -p "Partial stash"
# Git will prompt for each hunk
Including Untracked Files
# Stash including untracked files
git stash -u
# or
git stash --include-untracked
# Stash everything including ignored files
git stash -a
# or
git stash --all
Working with Multiple Stashes
# List all stashes with details
$ git stash list
stash@{0}: WIP on feature: 3d4f5g6 Add validation
stash@{1}: On main: 1a2b3c4 Dashboard updates
stash@{2}: WIP on bugfix: 7h8i9j0 Fix memory leak
# Apply specific stash
git stash apply stash@{1}
# Drop specific stash
git stash drop stash@{1}
# Show stash contents
git stash show stash@{0}
git stash show -p stash@{0} # Full diff
Creating Branches from Stash
Turn stashed work into a proper branch:
# Create branch from latest stash
git stash branch new-feature-branch
# Create branch from specific stash
git stash branch experimental-feature stash@{2}
This is particularly useful when you realize your stashed changes deserve their own branch.
Stash Workflow Patterns
Pattern 1: The Interrupted Developer
#!/bin/bash
# Alias for quick stash and switch
git config --global alias.switch-wip '!f() {
git stash save "WIP: $(git branch --show-current) $(date +%Y-%m-%d_%H:%M)"
git checkout $1
}; f'
# Usage
git switch-wip main
Pattern 2: The Experimenter
# Save current state before experimenting
git stash save "Before experimental changes"
# Try risky changes
git add .
git commit -m "Experimental: New algorithm"
# If it doesn't work out
git reset --hard HEAD~1
git stash pop
# If it works, keep the commit and drop the stash
git stash drop
Pattern 3: The Reviewer
# Reviewing a colleague's PR
git stash save "My work before code review"
git fetch origin
git checkout origin/colleague-feature
# Review and test their code...
# Return to your work
git checkout my-branch
git stash pop
Managing Your Stash Stack
Cleaning Up Old Stashes
# View old stashes
git stash list --date=relative
# Clear all stashes (careful!)
git stash clear
# Remove stashes older than 30 days
git reflog expire --expire-unreachable=30.days refs/stash
Stash Naming Convention
Develop a consistent naming pattern:
# Format: [TYPE]: [BRANCH] - [DESCRIPTION]
git stash save "WIP: feature/auth - Adding JWT validation"
git stash save "EXPERIMENT: main - Trying new build config"
git stash save "REVIEW: pr-123 - Before reviewing PR #123"
git stash save "BACKUP: release - Before risky merge"
Practical Examples
Example 1: Multi-Feature Development
# Working on feature A
git checkout feature-a
# ... make changes ...
# Need to switch to feature B
git stash save "FEATURE-A: Implementing user service"
git checkout feature-b
# ... make changes ...
# Switch back to feature A
git stash save "FEATURE-B: Adding API endpoints"
git checkout feature-a
git stash apply stash@{1} # Apply feature A stash
Example 2: Stash for Clean Testing
#!/bin/bash
# Script to test with and without local changes
echo "Testing with local changes..."
npm test
git stash save "Testing: Temporary stash for clean test"
echo "Testing without local changes..."
npm test
git stash pop
echo "Tests complete, changes restored"
Example 3: Partial Stashing
# You've made changes to multiple features
$ git status
modified: src/auth/login.js
modified: src/auth/register.js
modified: src/dashboard/chart.js
modified: src/dashboard/table.js
# Stash only dashboard changes
$ git stash push -m "Dashboard updates" src/dashboard/*
# Commit auth changes
$ git add src/auth/*
$ git commit -m "Complete authentication module"
# Bring back dashboard changes
$ git stash pop
Recovering Lost Stashes
If you accidentally drop a stash:
# Find the dropped stash
git fsck --unreachable | grep commit | cut -d' ' -f3 | xargs git log --oneline --no-walk
# Once you find it, recover it
git stash apply <commit-sha>
Stash Best Practices
1. Use Descriptive Messages
# Bad
git stash
# Good
git stash save "WIP: Refactoring payment processing with Stripe v3"
2. Don't Use Stash for Long-term Storage
# If keeping changes for more than a day, use a branch
git checkout -b temp/work-in-progress
git add .
git commit -m "WIP: Save current progress"
3. Regular Stash Cleanup
# Weekly cleanup alias
git config --global alias.stash-cleanup '!f() {
echo "Current stashes:"
git stash list
read -p "Clear all stashes? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
git stash clear
echo "All stashes cleared"
fi
}; f'
4. Combine with Other Git Features
# Stash before interactive rebase
git stash
git rebase -i HEAD~3
git stash pop
# Stash before bisect
git stash
git bisect start
# ... bisect process ...
git bisect reset
git stash pop
Common Issues and Solutions
Merge Conflicts After Pop
# If git stash pop causes conflicts
$ git stash pop
Auto-merging src/index.js
CONFLICT (content): Merge conflict in src/index.js
# Resolve conflicts manually, then
git add .
git stash drop # Remove the applied stash manually
Stash Won't Apply Cleanly
# Create a new branch for the stash
git stash branch stash-recovery
# Now you can resolve issues and merge properly
git add .
git commit -m "Recover stashed changes"
git checkout main
git merge stash-recovery
Automating Stash Workflows
Git Hooks for Auto-stashing
#!/bin/sh
# .git/hooks/pre-rebase
# Auto-stash before rebase
if ! git diff-index --quiet HEAD --; then
echo "Stashing changes before rebase..."
git stash save "AUTO: Pre-rebase stash $(date +%Y-%m-%d_%H:%M)"
fi
Stash Status in Your Prompt
# Add to .bashrc or .zshrc
git_stash_count() {
local stash_count=$(git stash list 2>/dev/null | wc -l | tr -d ' ')
if [ "$stash_count" -gt 0 ]; then
echo " (stash: $stash_count)"
fi
}
# Include in your prompt
PS1='[\u@\h \W$(git_stash_count)]\$ '
Conclusion
Git stash is more than just a temporary storage—it's a powerful tool for managing your workflow. It enables you to be more flexible, respond quickly to changing priorities, and experiment freely without fear of losing work.
Master these stash techniques, and you'll find yourself working more confidently and efficiently. Remember: stash is for temporary storage. For anything you want to keep longer than a day or two, create a proper branch instead.
The key to effective stashing is organization and regular cleanup. Develop your own stash workflow that fits your development style, and you'll wonder how you ever worked without it.
Share this article
David Childs
Consulting Systems Engineer with over 10 years of experience building scalable infrastructure and helping organizations optimize their technology stack.