Git Stash: Save Your Work Without Committing
Introduction
You're halfway through a feature. Files are modified, new code is partially written, and nothing is in a committable state. Then your team lead pings you — there's a critical bug on main that needs a hotfix right now.
You can't commit half-finished work. You don't want to lose it. You need to switch branches cleanly. This is exactly the problem git stash was built to solve.
It's one of those commands that seems simple on the surface but has enough depth to genuinely change how you work once you understand it fully. Let's break it down.
What Is Git Stash?
git stash takes your uncommitted changes — both staged and unstaged — and saves them to a temporary storage area outside of your normal commit history. Your working directory is then reverted to match the last commit, leaving you with a clean state.
Think of it as a clipboard for your in-progress work. You cut your changes, do whatever you need to do, and paste them back when you're ready.
Importantly, stashes are stored locally in a stack structure (last in, first out). They aren't pushed to remotes, so they're purely a local convenience tool.
Basic Stash Usage
Stashing Your Changes
# Stash all tracked, modified files (staged + unstaged)
git stash
# Stash with a descriptive message (highly recommended)
git stash push -m "WIP: login form validation logic"
Always use a message. When you have multiple stashes, stash@{3}: WIP on feature/login tells you nothing. A descriptive message saves you from guessing later.
Restoring Your Changes
# Apply the most recent stash and keep it in the stash list
git stash apply
# Apply the most recent stash and remove it from the list
git stash pop
The difference matters: apply keeps the stash around as a backup, while pop removes it after applying. I default to apply for important work and only drop the stash after confirming everything looks right.
Viewing Your Stashes
# List all stashes
git stash list
# Example output:
# stash@{0}: On feature/login: WIP: login form validation logic
# stash@{1}: On main: quick experiment with caching
# stash@{2}: On feature/dashboard: responsive grid layout
Inspecting a Stash
# See what files were changed in a stash
git stash show stash@{0}
# See the full diff
git stash show -p stash@{0}
Managing Multiple Stashes
The stash is a stack. By default, commands operate on stash@{0} (the most recent), but you can target any stash by index.
# Apply a specific stash
git stash apply stash@{2}
# Pop a specific stash
git stash pop stash@{1}
# Drop a specific stash without applying it
git stash drop stash@{0}
# Nuclear option — clear every stash
git stash clear
⚠️ WARNING: git stash clear is irreversible. There's no reflog for stashes once they're cleared. Use it deliberately, not casually.
A practical tip: if your stash list grows beyond three or four entries, something is off with your workflow. Stashes are meant to be temporary. If you're hoarding them, consider committing that work to a WIP branch instead.
Advanced Stash Techniques
Including Untracked Files
By default, git stash only saves tracked files. New files you haven't added yet are left behind — which can surprise you.
# Include untracked files
git stash push -u -m "WIP: includes new config file"
# Include untracked AND ignored files (rare, but useful)
git stash push -a -m "WIP: full workspace snapshot"
Stashing Specific Files
You don't have to stash everything. Target specific files or directories when you only want to set aside part of your work.
# Stash only specific files
git stash push -m "stash only auth changes" src/auth.ts src/middleware.ts
# Stash interactively — choose hunks to stash (like git add -p)
git stash push -p -m "partial stash: just the API changes"
Creating a Branch From a Stash
This is underused and incredibly handy. If your stash conflicts with the current branch state, or if you realize the stashed work deserves its own branch:
# Create a new branch from the commit where the stash was made,
# apply the stash, and drop it if successful
git stash branch feature/rescued-work stash@{0}
This checks out the exact commit where you created the stash, creates a new branch, applies the stash cleanly (no conflicts guaranteed), and drops it. It's the safest way to recover stashed work that no longer applies cleanly.
Stashing Only Staged Changes
# Stash only what's in the staging area
git stash push --staged -m "stash staged changes only"
This is useful when you've carefully staged specific changes and want to test the rest of your working directory in isolation.
Stash vs Alternatives
git stash isn't always the best tool. Here's how it compares to other approaches for saving in-progress work:
| Approach | When to Use | Trade-offs |
|---|---|---|
git stash |
Quick context switch, coming back within minutes or hours | Local only, easy to forget, no history |
| WIP commit | Saving progress when you might not return for days | Clutters history (clean up later with interactive rebase) |
| Temporary branch | Experimental work you may or may not come back to | More explicit, pushed to remote as backup if needed |
git worktree |
Working on two branches simultaneously without stashing | Requires disk space, slightly more setup |
My rule of thumb: if I'll be back within an hour, I stash. If it's longer, I make a WIP commit on the feature branch. If I'm not sure I'll come back, I push a temporary branch so it exists on the remote.
Common Pitfalls
1. Forgetting that stashes exist.
This is the most common problem. You stash something, move on, and completely forget about it. Weeks later you run git stash list and find orphaned work. Set a habit: if you stash, apply or branch it the same day.
2. Stash conflicts on apply.
If the branch has changed significantly since you stashed, applying can produce conflicts. When this happens, Git leaves the stash in the list even after pop. Resolve the conflicts, verify your work, and then manually drop the stash with git stash drop.
3. Stashing without a message.
The default message is auto-generated from the branch name and last commit, which is rarely helpful when you have multiple stashes. Always use -m.
4. Assuming untracked files are included.
They're not, by default. If you created new files, use the -u flag or you'll switch branches and wonder where your files went.
5. Using stash as long-term storage.
Stashes have no remote backup, no branch protection, and no review process. They're a temporary tool. If work matters, give it a proper commit and branch.
Real-World Scenarios
Scenario 1: Urgent Hotfix Mid-Feature
# You're on feature/dashboard with uncommitted changes
git stash push -u -m "WIP: dashboard chart component"
# Switch to main, create hotfix
git checkout main
git checkout -b hotfix/payment-bug
# ... fix the bug, commit, merge, done ...
# Come back to your feature
git checkout feature/dashboard
git stash pop
Scenario 2: Testing Without Your Local Changes
# Stash your changes to test the "clean" version
git stash push -m "temporarily removing my changes for testing"
# Run tests on the clean branch
npm test
# Bring your changes back
git stash pop
Scenario 3: Moving Accidental Changes to the Right Branch
# Oops — you started coding on main instead of a feature branch
git stash push -m "work that belongs on feature/search"
# Create and switch to the correct branch
git checkout -b feature/search
# Apply the stash here
git stash pop
This happens more often than anyone admits. Stash makes it a 10-second fix instead of a headache.
Conclusion
git stash is a small command with an outsized impact on your daily workflow. It removes the friction from context switching, lets you experiment safely, and rescues misplaced work in seconds.
The key principles to remember: always stash with a message, use -u when you have new files, don't let stashes pile up, and reach for git stash branch when a stash no longer applies cleanly.
It's not glamorous, but it's the kind of tool that quietly makes you faster every single day. Learn it once, use it forever.