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/
A full stash against a pathspec stashA plain git stash takes every tracked change and resets the whole working tree. A pathspec stash takes only the files you name and leaves every other change in place, so you can keep working on the rest.git stashgit stash push -- <paths>files stashedall modified trackedonly matching pathsworking tree aftercleanothers still modifiedindex afterresetothers' staging keptthe message flag (-m) matters more for partial stashes — you will have several

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
Ways to select what goes into a stashPathspecs select by file. --patch selects by hunk interactively. --staged selects whatever is in the index. --keep-index stashes everything but leaves the staged changes in the working tree, which is how you test a commit before making it.-- pathsby file or glob--patchby hunk--stagedthe index only--keep-indexall, keep stagedin place--keep-index still puts staged changes in the stash too — popping restores them twice

--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.

Several partial stashes from one working treeOne working tree with mixed changes can be split into several stashes, each with its own message: debugging output, local configuration and a prototype. The real fix stays in the working tree to be committed, and each stash can later be applied on its own.splitting mixed work by intentWorking tree (kept)src/export/schedule.py — the fixstash@{0}temporary print statements (--patch)stash@{1}debug logging + local config (paths)stash@{2}new exporter prototype (-u, dir)descriptive -m messages are what make several stashes manageable

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 with git 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.