git stash
Beginner Git CLI Careful
Summary: git stash saves the working tree's and staging area's uncommitted changes in a local stack and resets them, so you can switch branches or pull; git stash pop brings them back.
Careful — nothing is destroyed by stashing, but stashes are local, unpushed and easy to forget, and drop or clear discards them.
What it does
Records the current unstaged and staged changes as a hidden pair of commits under refs/stash, then restores the working tree and staging area to HEAD. pop reapplies the newest entry and removes it; apply reapplies without removing; drop removes without reapplying.
Why it exists
Git refuses to switch branches or merge when uncommitted changes would be overwritten, and half-finished work is not always ready for a commit. Stash is the parking space.
When to use it
- Switching branches or pulling with uncommitted edits that are not ready to commit.
- Setting an experiment aside for a few minutes to check something on a clean tree.
When not to use it
- For work you will keep more than a day: commit on a branch instead; branches are visible, pushable and reviewable.
- As a backup: stashes never leave your computer.
Syntax
| Form | Meaning |
|---|---|
git stash |
Stash tracked changes (staged and unstaged) |
git stash push -m "<message>" |
The same with a name; always name stashes you keep |
git stash -u |
Include untracked files |
git stash list |
Show the stack: stash@{0} is the newest |
git stash show [-p] [stash@{n}] |
Files (or full diff with -p) of an entry |
git stash pop [stash@{n}] |
Reapply and remove |
git stash apply [stash@{n}] |
Reapply and keep |
git stash drop [stash@{n}] |
Delete one entry |
git stash clear |
Delete all entries |
Examples
$ git status -s M docs/getting-started.md
?? docs/draft.md$ git stash push -u -m "getting-started notes"Saved working directory and index state On main: getting-started notes$ git stash liststash@{0}: On main: getting-started notes$ git stash show docs/getting-started.md | 2 ++
1 file changed, 2 insertions(+)$ git stash popOn branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: docs/getting-started.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
docs/draft.md
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (3086da7f103932365dc0761cf2ca49460809152c)
The situation that calls for it:
$ git switch feature/21-difficulty-filtererror: Your local changes to the following files would be overwritten by checkout:
README.md
Please commit your changes or stash them before you switch branches.
AbortingExpected result
After stash: a clean tree (untracked files remain unless -u) and one more entry in the list. After pop: the changes are back as unstaged edits (staged state is not restored unless --index), and the entry is gone.
Common mistakes
- Popping on the wrong branch. Changes apply wherever you are; check the branch line of
git statusfirst. - Forgetting
-u. Untracked files stay in the working tree and can be affected by the switch. - A stack of unnamed stashes. Name them; clear old ones.
- Pop with a conflict. The stash stays; resolve the file, then
git stash drop.
How to undo or recover
- Popped too early:
git stashagain. - Dropped by mistake: the hash printed by
Dropped refs/stash@{0} (…)can be reapplied for a while withgit stash apply <hash>; the reflog lesson explains why (lesson 12.1).
In VS Code
Source Control → … → Stash (Stash, Stash (Include Untracked), Pop Latest Stash, Pop Stash…, Apply, Drop).
In IntelliJ IDEA
Git → Uncommitted Changes → Stash Changes… / Unstash Changes…; or IntelliJ's own Shelve, which is not a Git stash but does the same job inside the IDE.
Related commands
git restore discards instead of parking · git switch and git pull are what usually demand a stash · git commit on a branch is the better choice for longer-lived work.