Stashing only some files with pathspecs Jump to heading
git stash with no arguments takes everything: every modified tracked file, staged and unstaged, goes into the stash and the working tree is reset. Often that is too much. You want to set aside the debugging changes in two files while keeping the real fix you are about to commit, or stash a half-finished refactor of one module so you can test the rest. Since Git 2.13, git stash push accepts pathspecs, and with --patch and (since 2.35) --staged you can stash precisely the part of your work you choose. This page shows each form and how they interact with the index, within stashing and work-in-progress recovery.
When to use this approach Jump to heading
- Your working tree mixes changes you want to keep working on with changes you want to park.
- You need a clean state for some files — to run a test or reproduce a bug — but not for all of them.
- You staged exactly what you want to keep, and want to stash everything else, or the reverse.
- If the parked work is substantial or long-lived, a branch or worktree is safer; see stash vs worktree vs WIP commit.
Step 1 — Stash specific files or directories Jump to heading
Pass pathspecs after --. Only matching files are stashed and reset; everything else stays as it is.
git status --short
# M src/export/schedule.py <- the fix: keep
# M src/export/debug_log.py <- debug noise: stash
# M config/local.yml <- local tweak: stash
git stash push -m "debug logging + local config" -- src/export/debug_log.py config/local.yml
git status --short # only schedule.py remains modified Pathspecs accept globs and directories, with the same rules as other Git commands.
git stash push -m "all fixture regeneration" -- 'tests/fixtures/**/*.json'
git stash push -m "docs work" -- docs/ Step 2 — Stash individual hunks with --patch Jump to heading
When the change you want to park is mixed into a file you are otherwise keeping, stash by hunk. --patch walks through each change and asks whether to stash it, the same interface as git add -p.
git stash push --patch -m "temporary print statements"
# Stash this hunk [y,n,q,a,d,s,e,?]? y = stash it, n = keep it, s = split smaller # Verification: the stash contains only the chosen hunks
git stash show -p stash@{0}
git diff # the hunks you kept are still in the working tree Step 3 — Stash only what is staged, or only what is not Jump to heading
Two flags use the index as the selection. --staged stashes exactly what you staged and leaves unstaged changes alone. --keep-index does the opposite of what people expect: it stashes everything but keeps the staged changes in place too.
# Park exactly what is staged
git add src/export/debug_log.py
git stash push --staged -m "staged debug changes"
# Test exactly what you are about to commit: stash unstaged work, keep the index
git stash push --keep-index -m "unstaged leftovers"
make test
git stash pop --keep-index has a subtlety: the staged changes are both kept in the working tree and recorded in the stash. Popping it later can conflict with themselves if you modified those files in between. Prefer --staged with the opposite selection when you can.
Step 4 — Include untracked files in a partial stash Jump to heading
Pathspec stashes ignore untracked files unless you add --include-untracked. Combine them to stash new files along with modified ones under a directory.
git stash push --include-untracked -m "new exporter prototype" -- src/export/prototype/
git status --short src/export/prototype/ # gone: modified and new files stashed The details of untracked and ignored files are in stashing untracked and ignored files.
Step 5 — Restore a partial stash Jump to heading
Apply or pop a partial stash as usual. Because it touches only some paths, it rarely conflicts with work you kept, but it can if you changed the same files since.
git stash list
# stash@{0}: On feature/export: temporary print statements
# stash@{1}: On feature/export: debug logging + local config
git stash pop stash@{1} To restore only one file from a stash, check it out from the stash commit rather than applying the whole stash.
git checkout stash@{1} -- config/local.yml ⚠️ SAFETY WARNING:
git checkout stash@{1} -- <path>overwrites that file in your working tree without merging, discarding any changes you made to it since stashing. Check withgit diff -- <path>first. The stash itself is unchanged, so you can apply it properly afterwards if you need to.
Validation checklist Jump to heading
Frequently Asked Questions Jump to heading
Why does git stash -- file not work on my machine? Jump to heading
Pathspec stashing needs Git 2.13 or newer, and the push subcommand is implied only in newer versions. Write git stash push -- file explicitly to be safe.
Can I stash a file that is not modified? Jump to heading
No — there is nothing to record. Stash works on differences from HEAD. An unmodified file is unaffected by any stash command.
What happens if I stash a renamed file by its new path only? Jump to heading
A rename is a deletion plus an addition. Stashing only the new path leaves the deletion behind. Include both paths in the pathspec, or stage the rename and use --staged.
Related Jump to heading
- Stashing & Work-in-Progress Recovery — the parent topic.
- Inspecting a Stash Before Applying It — checking what a stash holds.
- Moving Uncommitted Work to the Right Branch — a common reason to stash part of your work.
- Running Prettier and ESLint Only on Staged Files — tools that stash unstaged work behind the scenes.