git stash saves your uncommitted changes (both staged and unstaged) onto a stack and resets the working tree to the last commit. It is the standard answer to "I'm in the middle of something but I urgently need to switch branches / pull / try a clean build".
Unlike a commit, a stash is a private, local entry — it does not move with branches, it is not pushed to a remote, and it survives across branch switches.
The commands you will actually use
git stash # stash tracked changes
git stash -u # also stash untracked files
git stash -a # stash everything, including ignored files
git stash list # show the stack
git stash show -p # show the diff of the latest stash
git stash pop # apply the latest stash and remove it
git stash apply # apply the latest stash but keep it
git stash drop # delete the latest stash
git stash clear # delete all stashes
Most workflows live inside those nine commands.
A typical workflow
You're editing files on feature/x and someone asks you to look at a hotfix branch.
git stash -u -m "WIP: feature x form validation"
git switch hotfix/login-bug
# fix and push the hotfix
git switch feature/x
git stash pop
-m attaches a message so you can identify the stash later — strongly recommended once you have more than one stash on the stack.
Inspecting stashes
git stash list
# stash@{0}: On feature/x: WIP: feature x form validation
# stash@{1}: On main: experimenting with new logger
Show the full diff for a specific stash:
git stash show -p stash@{1}
Show only file names:
git stash show stash@{1}
Apply vs pop
popapplies the stash and removes it from the stack on success.applyapplies the stash and keeps it on the stack.
Use apply when you want to try the stash on multiple branches, or when you're not sure the apply will be conflict-free and want to keep a safety net.
If pop hits a merge conflict, the stash is not dropped — git keeps it so you can retry. Resolve the conflict, then drop it manually:
git stash drop
Stashing only part of your changes
Only staged changes
git stash --staged
Useful when you've already git add-ed the cohesive part of your work and want to set the rest aside.
Interactive (hunk-by-hunk)
git stash -p
Git walks you through each hunk and asks whether to stash it. The same y/n/s/e/q/? interface as git add -p.
Untracked and ignored files
By default, git stash only saves changes to files git already knows about. New files you haven't git add-ed are left in place — which is almost never what you want.
git stash -u # include untracked files
git stash -a # include untracked AND ignored files
-a is rarely the right answer; it will sweep up node_modules/, build artifacts, and .env files. Reach for -u by default.
Turning a stash into a branch
If a stash has been sitting on the stack and the base branch has moved on, applying it can be messy. Spin it out into its own branch instead:
git stash branch feature/x-recover stash@{1}
This creates a new branch from the commit the stash was made against, applies the stash, and drops it. You then commit normally.
Practical recipes
"I forgot to stash the new files I just created"
git stash -u
"I want to peek at a stash without applying it"
git stash show -p stash@{0} | less
"I want to keep the stash but apply it now"
git stash apply stash@{0}
"I want to pop a specific stash, not the most recent one"
git stash pop stash@{2}
"I just want my workspace clean — I don't care about saving"
Don't use stash. Use:
git restore --staged --worktree .
git clean -fd # also wipes untracked files
That's destructive. Use stash if there's any chance you want the work back.
Pitfalls
- A stash is local. It does not move with
git push. If you switch machines, the stash stays behind. - Untracked files are not stashed by default. Use
-u. - Stashes can pile up.
git stash listregularly. Old stashes grow stale and conflict-prone. popafter a conflict still leaves the stash on the stack. Don't be surprised when it's still there.- A stash is not a backup. It lives in your local repo only. For anything important, make a real commit on a branch.
Recovering a dropped stash
If you git stash drop by mistake, the commit objects still exist for a while. Find them with:
git fsck --no-reflog | grep dangling
Each dangling commit prints a SHA. Inspect with git show <sha>. When you find the stash, restore it:
git stash apply <sha>
This works because a stash is internally just a commit (well, two — a working tree commit and an index commit), so it survives until git's garbage collection runs.
Summary
git stashshelves your work;git stash popbrings it back.- Use
-uto include untracked files,-mto label stashes, andgit stash listto keep an eye on the stack. - Prefer
applyoverpopwhen you want a safety net. - For long-lived work, convert the stash into a branch with
git stash branch. - Don't treat stash as a backup — it's a temporary holding pen.