Saving Changes (git stash push)
Saving a stash is how a stash session begins. The modern verb is git stash push — older docs and muscle memory use the bare git stash, which does exactly the same thing. This page covers every option you'll actually use: messages, file selection, interactive hunks, untracked/ignored files, and keeping the index intact.
The basic save
Two equivalent forms
# Classic, still works everywhere git stash # Modern, recommended — supports paths and more flags git stash push
Always give it a message
Named stashes are findable stashes
git stash push -m "WIP on login form, validation half done"
# Later:
git stash list
# stash@{0}: On feature/login: WIP on login form, validation half doneStash only specific paths
Pathspec form — note the -- separator
# Stash just one file, leave the rest dirty git stash push -m "experimental auth changes" -- src/auth.js # Stash a whole directory git stash push -m "ui rework" -- src/components/ # Stash everything except a specific path? Combine with pathspec magic: git stash push -- ":(exclude)src/big-generated-file.ts" .
The -- separates options from pathspecs and is required whenever paths could be ambiguous. Anything after -- is treated as files.
Interactive stashing (choose hunks)
Like git add -p, but for stash
git stash push -p -m "stash only the experimental bits" # Git walks each hunk and asks: # Stash this hunk [y,n,q,a,d,e,?]? # y - stash this hunk # n - do not stash this hunk # q - quit # a - stash this and all later hunks in this file # d - skip this and all later hunks in this file # e - manually edit the hunk # ? - help
Including untracked files
The -u flag
# Default: untracked files are LEFT in the working tree git stash push -m "missing scratch.txt" # Include untracked files too git stash push -u -m "includes new files" # or --include-untracked
Including ignored files
The -a flag (rare but exists)
git stash push -a -m "include build artifacts and node_modules" # or --all
-a includes everything -u does, plus files matched by .gitignore. You almost never want this — ignored files are ignored for a reason (build output, dependencies, caches). The one valid case is rescuing a one-off scratch file you forgot to un-ignore.
Keep the staging area intact
--keep-index for "test what I'm about to commit"
# Scenario: you have staged changes you want to commit, plus # unrelated dirty work in the tree. You want to run tests against # only the staged content. git stash push --keep-index -m "park unrelated edits" # Now the working tree contains exactly what is staged. # Run your tests, commit if green: npm test git commit -m "Add validation" # Bring back the parked edits git stash pop
What the result looks like
A clean tree, a populated stack
git status
# On branch feature/login
# nothing to commit, working tree clean
git stash list
# stash@{0}: On feature/login: WIP on login form
# stash@{1}: On main: hotfix scratch from yesterdayCommon errors
What you might see and what it means
$ git stash No local changes to save # Means: nothing is modified or staged. If you have new files, # they are untracked — try git stash -u . $ git stash push -- nope.txt error: pathspec 'nope.txt' did not match any file(s) known to git # Means: the file is untracked. Either git add it first, or use -u # without a pathspec.
Real-world recipe: pull --autostash
Let pull stash for you
# One-off: git pull --autostash # Forever: git config --global pull.rebase true git config --global rebase.autoStash true
With rebase.autoStash on, Git transparently stashes your dirty tree, pulls/rebases, and pops the stash back. You stop thinking about it.