Picture this: You're deep in the zone, refactoring a complex component, variables renamed, functions moved around, half-implemented features scattered across multiple files. Then your manager Slacks you: "Hey, can you quickly fix that critical bug on the main branch? Client is breathing down our necks."
Your heart sinks. You've got uncommitted changes everywhere, nothing is in a working state, and you need to switch branches right now. Sound familiar?
Until yesterday, I would have frantically tried to make sense of my mess, created a "WIP: don't look at this" commit, or worse—lost hours of work trying to manually save and restore my changes. Then I discovered Git stash, and it literally saved my career (okay, maybe just my afternoon, but it felt career-saving).
The "Oh Crap" Moment We've All Had
bash
The nightmare scenario
$ git status
On branch feature/user-dashboard
Changes not staged for commit:
modified: src/components/UserProfile.js
modified: src/utils/dataHelpers.js
modified: src/styles/dashboard.css
deleted: src/components/OldUserCard.js
Untracked files:
src/components/NewUserCard.js
src/hooks/useUserData.js
src/types/user.ts
Manager: "Can you fix the login bug on main branch ASAP?"
Me: internal screaming
$ git checkout main
error: Your local changes to the following files would be overwritten by checkout:
src/components/UserProfile.js
src/utils/dataHelpers.js
Please commit your changes or stash them before you switch branches.
This is where most of us panic. We either:
- Make a messy commit we'll regret later
- Copy files to random folders (been there)
- Spend 20 minutes trying to figure out what's safe to discard
- Question our life choices
But there's a better way.
Enter Git Stash: Your Code's Safety Net
Git stash is like having a magical pocket dimension where you can temporarily store your messy, half-finished work and come back to it later—exactly as you left it.
bash
The magic command that saved my sanity
$ git stash
Saved working directory and index state WIP on feature/user-dashboard: a1b2c3d Add user profile component
That's it. One command, and all your uncommitted changes are safely tucked away. Your working directory is now clean, and you can switch branches freely.
bash
Now this works perfectly
$ git checkout main
Switched to branch 'main'
Fix the critical bug
$ git add .
$ git commit -m "Fix login validation bug"
Switch back to your feature branch
$ git checkout feature/user-dashboard
Restore your messy work exactly as it was
$ git stash pop
Git Stash: More Powerful Than You Think
Basic Stash Operations
bash
Save current work with a custom message
$ git stash save "WIP: refactoring user dashboard components"
List all your stashes
$ git stash list
stash@{0}: On feature/user-dashboard: WIP: refactoring user dashboard components
stash@{1}: On feature/api-integration: WIP: adding error handling
stash@{2}: On main: WIP: updating documentation
Apply a specific stash without removing it from stash list
$ git stash apply stash@{1}
Apply and remove the most recent stash
$ git stash pop
Remove a stash without applying it
$ git stash drop stash@{1}
Clear all stashes (be careful!)
$ git stash clear
Advanced Stash Techniques That Blew My Mind
- Stashing Only Specific Files
bash
Only stash changes to specific files
$ git stash push -m "Stashing only the CSS changes" src/styles/dashboard.css
Stash everything except specific files
$ git stash push -m "Everything except the config" -- . ':!config/database.js'
- Stashing Untracked Files Too
bash
Include untracked files in your stash
$ git stash -u
Include untracked AND ignored files
$ git stash -a
- Interactive Stashing (The Game Changer)
bash
Choose exactly what to stash, line by line
$ git stash -p
Git will ask you about each change:
Stage this hunk [y,n,q,a,d,e,?]?
This is incredible when you have multiple unrelated changes mixed together and only want to stash some of them.
Real-World Scenarios Where Git Stash Saved My Life
Scenario 1: The Emergency Hotfix
bash
Working on a feature, lots of uncommitted changes
$ git status
... tons of modified files ...
Emergency: production is down, need to hotfix NOW
$ git stash save "Feature work in progress - dashboard refactor"
$ git checkout main
$ git pull origin main
Create hotfix branch
$ git checkout -b hotfix/critical-login-bug
... fix the bug ...
$ git add .
$ git commit -m "Fix critical login validation bug"
$ git push origin hotfix/critical-login-bug
Back to feature work
$ git checkout feature/user-dashboard
$ git stash pop
Continue where I left off, nothing lost!
Scenario 2: The "Let Me Try Something" Experiment
bash
In the middle of implementing a feature
$ git stash save "Current implementation - working but slow"
Try a completely different approach
... experiment with new implementation ...
Experiment didn't work out
$ git reset --hard HEAD
$ git stash pop
Back to the working implementation!
Scenario 3: The Code Review Pivot
bash
Working on feature A
$ git stash save "Feature A - user authentication flow"
Code review comes in for feature B that needs immediate attention
$ git checkout feature/payment-integration
... address code review comments ...
$ git add .
$ git commit -m "Address code review feedback"
Back to feature A
$ git checkout feature/user-auth
$ git stash pop
Seamlessly continue where I left off
Pro Tips That Make Git Stash Even Better
- Descriptive Stash Messages Are Your Friend
bash
Bad
$ git stash
Good
$ git stash save "WIP: user dashboard - refactored components, need to fix CSS"
Even better
$ git stash save "Dashboard refactor: moved UserCard to separate component, updated props, CSS needs cleanup for mobile"
- Use Stash to Clean Up Your Commits
bash
You have a working feature but commits are messy
$ git log --oneline
a1b2c3d Fix typo
b2c3d4e Add user validation
c3d4e5f Fix validation again
d4e5f6g Actually fix validation this time
e5f6g7h Add user component
Stash any uncommitted changes
$ git stash
Interactive rebase to clean up commits
$ git rebase -i HEAD~5
... squash and reword commits ...
Apply stash back if needed
$ git stash pop
- Stash Branches for Complex Work
bash
Create a branch from a stash (mind = blown)
$ git stash branch new-feature-branch stash@{1}
This creates a new branch from the commit where the stash was created and applies the stash to it. Perfect for when you realize your stashed work should be a separate feature.
- Viewing Stash Contents Without Applying
bash
See what's in a stash
$ git stash show stash@{0}
See detailed diff
$ git stash show -p stash@{0}
Compare stash with current working directory
$ git diff stash@{0}
Git Stash Workflows That Changed My Development Process
The "Context Switching" Workflow
bash
My new daily routine:
Always stash before switching contexts
alias switch-to="git stash save 'Context switch' && git checkout"Use descriptive stash names for different work streams
$ git stash save "API integration - OAuth flow 80% complete"
$ git stash save "UI polish - working on responsive design"
$ git stash save "Bug investigation - memory leak in user service"Review stashes at end of day
$ git stash list
Decide what to commit, what to continue tomorrow
The "Experiment Safely" Workflow
bash
Before trying risky changes
$ git stash save "Stable version before performance optimization"
Try the risky change
... make experimental changes ...
If it works:
$ git add .
$ git commit -m "Successful performance optimization"
$ git stash drop Don't need the backup anymore
If it doesn't work:
$ git reset --hard HEAD
$ git stash pop Back to stable version
The "Code Review Ready" Workflow
bash
Working on feature with debug code, console.logs, etc.
$ git add .
$ git commit -m "Feature implementation (with debug code)"
Clean up for code review
$ git stash save "Debug code and temporary changes"
$ git reset --soft HEAD~1 Uncommit but keep changes staged
Remove debug code, clean up
$ git commit -m "Clean feature implementation"
If you need debug code back later:
$ git stash pop
Common Git Stash Gotchas (Learn From My Mistakes)
- Stash Conflicts
bash
When applying a stash creates conflicts
$ git stash pop
Auto-merging src/components/UserProfile.js
CONFLICT (content): Merge conflict in src/components/UserProfile.js
The stash entry is kept in case you need it again.
Resolve conflicts like any merge conflict
Edit the file, remove conflict markers
$ git add src/components/UserProfile.js
$ git stash drop Remove the stash since we've resolved it
- Stashing Doesn't Include New Files by Default
bash
This won't stash new files
$ git stash
This will include untracked files
$ git stash -u
This will include untracked AND ignored files
$ git stash -a
- Stash vs. Commit Decision
bash
When to stash vs. commit:
Stash when:
- Work is incomplete/broken
- Temporary debugging code
- Experimental changes
- Need to switch contexts quickly
Commit when:
- Work is complete and tested
- Logical unit of work
- Want to share with team
- Part of permanent project history
Advanced Git Stash Tricks
- Partial Stashing with Pathspecs
bash
Stash only JavaScript files
$ git stash push -m "JS changes only" ".js"
Stash everything in src/ directory
$ git stash push -m "Source code changes" src/
Stash everything except tests
$ git stash push -m "Non-test changes" -- . ':!/test'
- Stash and Immediately Apply to Different Branch
bash
Stash changes and apply to different branch in one go
$ git stash
$ git checkout other-branch
$ git stash pop
Or create a new branch with the stash
$ git stash branch new-branch-name
- Using Stash in Scripts
bash
!/bin/bash
Script to safely pull latest changes
Check if there are uncommitted changes
if ! git diff-index --quiet HEAD --; then
echo "Stashing uncommitted changes..."
git stash save "Auto-stash before pull $(date)"
STASHED=true
fi
Pull latest changes
git pull origin main
Restore stashed changes if any
if [ "$STASHED" = true ]; then
echo "Restoring stashed changes..."
git stash pop
fi
Git Stash vs. Other Solutions
Why Not Just Commit?
bash
The "WIP commit" approach (what I used to do)
$ git add .
$ git commit -m "WIP - don't look at this mess"
$ git checkout main
... fix bug ...
$ git checkout feature-branch
$ git reset --soft HEAD~1 Undo the WIP commit
The stash approach (so much cleaner)
$ git stash save "Work in progress - refactoring components"
$ git checkout main
... fix bug ...
$ git checkout feature-branch
$ git stash pop
Why Not Copy Files Manually?
bash
The manual backup approach (my dark past)
$ cp -r src/ ../backup-src/
$ git checkout main
... fix bug ...
$ git checkout feature-branch
$ cp -r ../backup-src/ src/
$ rm -rf ../backup-src/
Problems with this approach:
- Doesn't preserve git state
- Easy to forget what you were doing
- No version history
- Can't easily see what changed
- Prone to human error
Building Git Stash Into Your Daily Workflow
My New Git Aliases
bash
Add these to your ~/.gitconfig
[alias]
Quick stash with timestamp
stash-quick = "!git stash save \"Quick stash $(date)\""
Stash with interactive selection
stash-pick = stash save --patch
List stashes with better formatting
stash-list = stash list --pretty=format:'%C(red)%h%C(reset) - %C(dim yellow)(%C(bold magenta)%gd%C(dim yellow))%C(reset) %<(70,trunc)%s %C(green)(%cr) %C(bold blue)<%an>%C(reset)'
Show stash contents
stash-show = "!f() { git stash show -p ${1:-stash@{0}}; }; f"
Apply stash and remove it
stash-apply-drop = "!f() { git stash apply ${1:-stash@{0}} && git stash drop ${1:-stash@{0}}; }; f"
Integration with VS Code
If you're using VS Code, the GitLens extension makes stash management visual and intuitive:
- View all stashes in the sidebar
- Apply/drop stashes with clicks
- See stash diffs inline
- Create stashes from the command palette
Team Workflow Integration
bash
Team standup script
!/bin/bash
echo "=== Current Work Status ==="
echo "Branch: $(git branch --show-current)"
echo "Uncommitted changes: $(git status --porcelain | wc -l) files"
echo "Stashed work:"
git stash list | head -3
echo ""
echo "=== Today's Plan ==="
... rest of standup script
The Mindset Shift: From Fear to Freedom
Before discovering git stash, I lived in constant fear of:
- Losing work when switching branches
- Making messy commits just to save state
- Forgetting what I was working on
- Breaking things while experimenting
Now I work with confidence, knowing that:
- I can safely experiment without fear
- Context switching is painless
- My work is always recoverable
- I can maintain clean commit history
Conclusion: Git Stash Changed How I Code
Git stash isn't just a command—it's a mindset shift. It transforms you from someone who's afraid to experiment and switch contexts into someone who can work fluidly across multiple features, bugs, and experiments.
Key takeaways:
- Always stash before switching contexts - make it a habit
- Use descriptive stash messages - your future self will thank you
- Don't be afraid to experiment - stash gives you a safety net
- Keep your commit history clean - use stash instead of WIP commits
- Learn the advanced features - partial stashing and stash branches are game-changers
My new workflow:
bash
Starting work
$ git stash list See what I was working on
Switching contexts
$ git stash save "Detailed description of current work"
Experimenting
$ git stash save "Stable version before trying X"
End of day
$ git stash list Review what needs to be finished tomorrow
Git stash turned me from a developer who was constantly stressed about losing work into someone who can confidently juggle multiple features, experiment freely, and maintain clean git history.
If you're not using git stash yet, start today. Your future self (and your stress levels) will thank you.
What's your biggest "git stash saved my life" moment? Share it in the comments—I'd love to hear how this simple but powerful feature has helped other developers!
Useful Git Stash Resources:
git productivity webdev programming versioncontrol
Top comments (0)