Lesson 15 of 30
You need to switch branches but your work isn't commit-ready. git stash shelves it temporarily — but a real WIP commit is sometimes the better call.
12 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
This topic is about judgment and practical tradeoffs more than a single right answer — a mock interview is the better way to test yourself on it.
Be interviewed on this →Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
git stash takes everything uncommitted in your working directory and staging area — tracked changes, not new untracked files by default — and saves it off to the side as a special kind of commit, then resets your working directory back to match HEAD. Your branch looks clean again, as if you'd never touched anything, but the work isn't gone: it's sitting in a stack you can pop back at any time, on any branch.
The classic trigger is an interruption: you're mid-change on a feature branch, and someone needs you to check out main right now to look at something urgent. Your changes aren't ready to commit — half-finished, maybe don't even compile — but git switch main will refuse if those changes would conflict with files that differ between branches. Stashing clears the way.
Mid-edit, uncommitted, and asked to switch branches immediately:
$ git status
modified: components/SearchBar.tsx
modified: lib/search/query.ts
$ git switch main
error: Your local changes to the following files would be overwritten by checkout:
components/SearchBar.tsx
Please commit your changes or stash them before you switch branches.
Stash it, with a message so future-you knows what's in it:
$ git stash push -m "wip: search debounce, not compiling yet"
Saved working directory and index state On feature/search-debounce: wip: search debounce, not compiling yet
$ git status
nothing to commit, working tree clean
$ git switch main
Switched to branch 'main'
Working tree is clean, branch switch goes through. Do whatever the interruption needed. Come back and check what's stashed:
$ git switch feature/search-debounce
$ git stash list
stash@{0}: On feature/search-debounce: wip: search debounce, not compiling yet
Bring it back with pop — applies the stash and removes it from the stack in one step:
$ git stash pop
On branch feature/search-debounce
Changes not staged for commit:
modified: components/SearchBar.tsx
modified: lib/search/query.ts
Dropped refs/stash@{0} (3f8e9a1...)
Exactly where you left off. If you'd rather keep the stash around after applying it — say, to apply the same change to a second branch too — use git stash apply instead of pop; apply doesn't remove it from the stack, so you'd need a separate git stash drop when you're actually done with it.
git added yet survives a plain git stash untouched on disk — which is usually fine, but confusing if you expected the stash to fully "clean" your working directory. Use git stash -u (--include-untracked) when you need those swept up too.git stash show -p stash@{0} to see the diff, versus just git log -p for a commit). If the interruption might last more than a few minutes, git commit -m "wip: search debounce" on the same branch is easier to find later and trivially undoable with git reset --soft HEAD~1 once you're back.main (or wherever you're popping onto) has diverged from where the stash was taken, you get real conflict markers to resolve — a stash isn't magically immune to the same three-way merge Git does everywhere else.Under the hood a stash is literally a commit object (actually two — one for the working directory state, one for the index) sitting outside any branch, findable only through git stash list, not git log. It's the same object model from the mental-model concept, just referenced by a different kind of pointer than a branch.