git stash — setting work aside without committing it

Sometimes you need a clean working directory right now — to switch branches, pull a fix, or check out something else — but the work in progress isn't done enough to commit. Stash is exactly the tool for that gap.

Intermediate

4 min read

The problem: work in progress, but you need a clean slate right now

$ git checkout main
error: Your local changes to the following files would be overwritten by checkout:
    app.py
Please commit your changes or stash them before you switch branches.

Mid-way through a change, uncommitted and not ready to be a real commit, something urgent comes up — a critical bug needs a quick fix on main, or a teammate needs the latest main pulled in before you can continue. Git actively prevents switching branches (from the branching lesson) when it would overwrite uncommitted changes — the options at that point are: commit work that isn't really done, discard it entirely, or stash it.

git stash: saving the working directory state, then reverting to clean

git stash
Saved working directory and index state WIP on feature-login: a3f8e21 Add login form

git stash takes all uncommitted changes (staged and unstaged) and saves them separately, in a stack of stashes, then reverts the working directory back to match the last commit — clean, as if the changes had never been made, but not lost. This is genuinely different from git commit: nothing about a stash becomes part of the project's permanent history the way a commit does; it's a temporary, local-only holding area for work that isn't ready to be a real commit yet.

git stash pop: getting the work back

git stash pop

git stash pop re-applies the most recently stashed changes to the working directory and removes that entry from the stash stack — this is normally the next step after whatever needed the clean working directory is done (the urgent fix is committed, the pull is complete), picking up exactly where the interrupted work left off. git stash apply does the same re-application but keeps the stash entry in the stack afterward, useful specifically when the same stashed changes might need to be applied more than once.

Multiple stashes: a real stack, not a single slot

git stash list
stash@{0}: WIP on feature-login: a3f8e21 Add login form
stash@{1}: WIP on main: 9c2d104 Update README

git stash can be called more than once, building up a genuine stack of independent saved states — git stash list shows all of them, most recent first. git stash pop (with no argument) always applies the most recent one; a specific older stash can be applied with git stash pop stash@{1}. This matters because it's easy to stash something, forget about it, and stash something else later — checking git stash list periodically is worth doing, since an old, forgotten stash entry is easy to lose track of.

What git stash doesn't do: it's not a substitute for committing

Bad habit:  stash something "for later" and never come back to it
Good habit: stash briefly, for a specific short interruption, then pop it back

A stash is meant for a brief, specific interruption — not a long-term parking spot for unfinished work. Stashed changes are local-only (never pushed to a remote, unlike commits from the working-with-remotes lesson), which means they're genuinely at risk of being lost — accidentally cleared, or simply forgotten about entirely as more stashes pile up on top. Work that's going to take a while, or that needs to survive across machines, belongs in an actual commit on a branch (even an unfinished, "WIP" commit is safer and more visible than an indefinitely-parked stash), not in the stash stack.

A practical use: stashing to test something on a clean tree

git stash                    # set aside current changes
npm test                       # run tests against the clean, last-committed state
git stash pop                   # bring the changes back

Beyond interruptions, stashing is also a quick way to temporarily see the project exactly as the last commit left it — confirming a test failure isn't actually caused by uncommitted changes, or checking that a build works cleanly before adding new work on top. This is a smaller, faster version of the same idea git diff (uncommitted changes) and git restore (discarding them) both serve — a genuinely low-friction way to look at "what does the last commit actually look like," without losing the in-progress work to get there.

Further reading

Check your understanding

A quick comprehension check — not tracked, not graded, just for you.

1. How is git stash genuinely different from git commit?

2. What's the difference between git stash pop and git stash apply?

3. Can multiple git stash calls coexist, or does a new stash overwrite the previous one?

4. Why is git stash a poor substitute for committing unfinished work that needs to survive across machines?