git stash takes the changes in your working tree, tucks them away on a stack, and gives you back a clean working directory matching the last commit. You get your work back later with git stash pop. The whole point is to set unfinished work aside without committing it, usually because something more urgent just came up.
git stash # save your changes, clean the working tree
git stash pop # bring the most recent stash back and remove it from the stack
That is the ninety-percent answer. The rest of this page covers the difference between pop and apply, how to stash files Git is not tracking yet, how to stash only some of your changes, and the everyday pattern of stashing so you can switch branches.
What git stash actually saves
By default git stash saves two things: changes to files Git already tracks, whether or not you have run git add on them, and your staged changes. It then resets your working tree to match HEAD, so the directory looks like a fresh checkout of your last commit.
What it does not save by default:
- Untracked files (new files you have never added). See stashing untracked files below.
- Ignored files (anything matched by your .gitignore rules).
So if you stash and then notice a brand-new file is still sitting there, that is expected. Git only stashed the things it was already watching.
If the distinction between tracked, staged, and untracked is fuzzy, the Git staging area walkthrough is worth reading first. Everything git stash does is built on those states.
Saving and restoring: pop vs apply
The two ways to get your work back are git stash pop and git stash apply. They both reapply the stashed changes to your working tree. The difference is whether the stash entry sticks around afterward.
| Command | Reapplies changes | Keeps the stash entry | Use when |
|---|---|---|---|
git stash pop | Yes | No (removes it from the stack) | The normal case: you want your work back and you are done with the stash |
git stash apply | Yes | Yes (entry stays on the stack) | You want to apply the same stash to more than one branch, or you want a safety copy until you confirm it applied cleanly |
In day-to-day work, pop is what you want. Reach for apply when you want to keep the stash around, then delete it yourself with git stash drop once you are sure it landed correctly.
git stash apply # reapply the latest stash, but leave it on the stack
git stash drop # then remove it manually when you are happyOne caution with pop: if reapplying the stash causes a merge conflict, Git does not drop the stash entry. That is deliberate, so you do not lose the work while resolving the conflict. Resolve it the same way you would resolve any merge conflict, then drop the stash by hand.
Naming a stash so you can find it later
A bare git stash records a generic message like WIP on main. If you stash often, give the entry a label so future-you knows what it holds.
git stash save "half-finished login form"git stash save -m "msg" (or just git stash save "msg") is the form for naming a stash. Plain git stash records a generic message; save lets you attach your own. Updated: Git 2.13 (May 2017) added git stash push, which deprecates save and reads more naturally (git stash push -m "half-finished login form"). Either works on a current Git; reach for push -m on anything modern.
Listing, inspecting, and dropping stashes
Stashes live on a stack, so you can have several at once. List them with:
git stash liststash@{0}: On main: half-finished login form
stash@{1}: WIP on feature/api: 9c3f1a2 add request loggingThe most recent stash is always stash@{0}. To see what a particular stash contains without applying it:
git stash show stash@{1} # summary of changed files
git stash show -p stash@{1} # the full diffTo apply or pop a specific stash rather than the latest, name it:
git stash pop stash@{1}
git stash apply stash@{1}To delete one stash, or clear the whole stack:
git stash drop stash@{1} # remove a single entry
git stash clear # remove every stash (no undo, be careful)git stash clear does not warn you. If you are unsure whether you still need something on the stack, list and inspect first.
Stashing untracked files
Because git stash ignores untracked files by default, a new file you just created stays in your working tree after a stash. To include untracked files, add -u (or the long form --include-untracked):
git stash -u # stash tracked changes AND untracked filesTo go further and also include files matched by .gitignore, use -a (--all):
git stash -a # stash everything, including ignored filesI reach for -a rarely. Ignored files are usually build output or local config you do not want moving around. Most of the time -u is the one you want when a stash leaves stray new files behind.
Stashing only some of your changes
Sometimes you only want to set aside part of your work and keep editing the rest. The -p (--patch) flag walks you through each change and asks, hunk by hunk, whether to stash it:
git stash -pGit shows each chunk of the diff and waits for a key. The ones worth knowing:
y - stash this hunk
n - do not stash this hunk
s - split this hunk into smaller pieces
q - quit, stash nothing more
? - show the full list of optionsThis is the same interactive patch interface git add -p uses, so if you already split commits with the staging area, it will feel familiar. Partial stashing is handy when one file holds two unrelated edits and you only want to hide one of them.
The pattern everyone uses: stash to switch branches
Here is the situation git stash was built for. You are partway through a change on one branch, and a bug report comes in that you need to fix on another branch right now. You are not ready to commit your half-done work, but Git will not let you switch branches if the checkout would overwrite your local edits (see local changes would be overwritten for that exact error).
Stash, switch, fix, switch back, pop:
git stash # set your half-done work aside
git checkout main # move to the branch with the bug
# ... fix the urgent bug, commit it, push ...
git checkout feature/login # back to where you were
git stash pop # your half-done work returnsOn a solo project that round trip is the whole story. On a team it sits inside a wider branching plan: the same instinct to keep a clean main branch and to follow one of the three branching strategies teams use is what makes the interruption above land on the right branch in the first place.
Updated: Git 2.23 (August 2019) added git switch as a clearer, dedicated alias for changing branches (git switch main / git switch feature/login). It does the same thing as git checkout <branch> here; use whichever your Git supports.
That round trip is the everyday use of stash. Your unfinished change never touches the commit history; it just rides along on the stack while you deal with the interruption.
Two honest caveats. Stash is for short detours, not long-term storage. A stash that sits for a week is a change you have half-forgotten and never reviewed; if work is worth keeping for any length of time, make a throwaway branch and a real commit instead, with a decent commit message. And a stash is local only: it never gets pushed to a remote, so it is not a backup. If you would be upset to lose it, commit it.
Recovering a stash you dropped by accident
If you git stash drop or git stash clear and then realize you needed that work, it is usually not gone yet. Stashes are commits under the hood, and dropped commits hang around in the reflog until garbage collection. The full recovery walkthrough is in recovering lost commits with git reflog, but the short version is to find the dangling stash commit and apply it:
git fsck --no-reflogs | grep commit # find dangling commits
git stash apply <commit-hash> # reapply the one you recogniseReplace the hash with the dangling commit that matches your lost work. This is a fallback, not a habit. The reliable move is to not clear a stack you have not inspected.
Where stash fits among the "undo" commands
Stash is one of several ways to deal with uncommitted work, and people often confuse it with discarding or resetting. They do different things:
| Goal | Command | Keeps your changes |
|---|---|---|
| Set work aside to bring back later | git stash | Yes (on the stack) |
| Throw work away entirely | git restore . (see discard local changes) | No |
| Move a finished change into history | git commit | Yes (as a commit) |
| Undo a commit you already made | depends; see undo the last commit and reset vs revert | depends |
If you want the work back later, stash. If you want it gone, discard. If it is done, commit. Reaching for stash to "undo" a commit is the common mistake; stash only ever touches the working tree and the index, never the commit history.
New to Git altogether? Start with Git for Beginners, which walks through the whole picture (working tree, staging area, commits, branches) that stash sits on top of.
Sources
Authoritative references this article was fact-checked against.
- git-stash: official Git documentationgit-scm.com
- Pro Git: Git Tools, Stashing and Cleaninggit-scm.com





