You’re halfway through a change, and need to switch branches to fix something urgent, or pull new commits, but your work isn’t ready to commit. git stash saves your uncommitted changes on a stack, and gives you a clean working directory. When you’re back, you reapply them.
Stash and restore
git stash push -m "WIP: invoice export" # save changes (tracked files)
git status # clean
git switch hotfix/login && … # do other work
git switch feature/invoice-export
git stash pop # reapply and remove from the stash
git stash without arguments is the same as git stash push, but a message (-m) makes the list readable later.
What gets stashed
By default: modified tracked files, staged and unstaged. Not included:
git stash push -u -m "with new files" # -u / --include-untracked: new files too
git stash push -a # -a / --all: also ignored files (rarely needed)
Forgetting -u is a common surprise: new files stay behind in the working directory.
List and inspect
git stash list
# stash@{0}: On feature/invoice-export: WIP: invoice export
# stash@{1}: WIP on main: 3f2a1c9 Fix typo
git stash show stash@{1} # files changed
git stash show -p stash@{1} # full diff
apply vs pop
| Command | Effect |
|---|---|
git stash apply [stash@{n}] |
Reapply, keep the stash entry |
git stash pop [stash@{n}] |
Reapply, and remove it if successful |
git stash drop stash@{n} |
Delete one entry |
git stash clear |
Delete all entries (careful) |
If applying causes conflicts, pop keeps the stash entry, so nothing is lost. Resolve the conflicts, git add the files, then git stash drop.
git stash apply --index also restores what was staged versus unstaged.
Stash only some changes
git stash push -m "only config" -- config/app.php # specific files
git stash push -p # interactively choose hunks
git stash push --staged # only staged changes (Git 2.35+)
Turn a stash into a branch
If the branch has moved on, and the stash no longer applies cleanly:
git stash branch feature/invoice-export-v2 stash@{0}
This creates a branch at the commit where you stashed, applies the stash there, and drops it if successful.
Recover a dropped stash
Dropped or cleared stashes are unreferenced commits, and are recoverable for a while:
git fsck --no-reflog | awk '/dangling commit/ {print $3}' | \
xargs -I{} git log -1 --format='%h %s' {} | grep -i "WIP\|On "
git stash apply <commit-hash>
See undo the last commit.
Good habits
- Stashes are local: they aren’t pushed, and they’re easy to forget. For anything longer than a quick switch, prefer a WIP commit on a branch (
git commit -m "WIP", later amended or squashed). - Use
git worktree add ../hotfix hotfix/loginto work on two branches at once, without stashing at all. - Clean up old entries with
git stash listfrom time to time.
Quick reference
| Task | Command |
|---|---|
| Save with message | git stash push -m "msg" |
| Include new files | git stash push -u |
| List | git stash list |
| Show diff | git stash show -p stash@{0} |
| Reapply and remove | git stash pop |
| Reapply, keep | git stash apply |
| Partial | git stash push -p / -- <files> |
| To branch | git stash branch <name> |
Related: git cherry-pick and Git commands cheat sheet.