Git Stashing
Temporarily save local working-tree and index state with precise control over tracked, untracked, ignored, staged, and path-limited changes.
Intermediate
Learner goal
By the end of this lesson, you should be able to save a dirty working-tree/index state in a stash, predict what the default stash contains, deliberately include untracked or ignored files, preserve staged changes when appropriate, stash only staged changes, and use a pathspec to limit which paths are stashed.
The problem stashing solves
Suppose your working tree contains unfinished changes, but you need a clean working tree temporarily. `git stash push` records the local modifications and then rolls the affected working-tree and index state back to `HEAD`. It does not create a commit on your current branch. The stash is separate from the branch history.
git status --short
git stash push -m "pause unfinished work"
git status --shortThe important model is a state transition: local tracked modifications are saved into a new stash entry, then the working tree and index for those stashed changes are restored to `HEAD`. The current branch tip does not move.
Quick check
After a successful default `git stash push`, what happens to the branch tip?
HEAD points to the current branch commit and the working tree has tracked edits.The tracked edits are stashed; HEAD still names the same branch commit.
`git stash` and `git stash push`
Modern Git documents `git stash` without a subcommand as equivalent to `git stash push`. Using the explicit `push` form makes the intent and its options clearer in teaching material. The older `git stash save` form is deprecated in favor of `git stash push`, so this lesson uses `push`.
git stash push -m "pause feature work"
# Equivalent short form when no subcommand is needed:
git stash -m "pause feature work"What the default stash includes
By default, `git stash push` saves changes to tracked files that are represented by the working tree and index. Untracked files are not included by default. Ignored files are also not included by default. This distinction matters because a clean status after stashing does not mean every file you created was saved.
printf 'tracked change\n' >> README.md
printf 'new file\n' > draft.txt
git status --short
git stash push -m "tracked only"
git status --short
# draft.txt is still untrackedQuick check
Which statement is correct for a default `git stash push`?
The repository contains a modified tracked file and a newly created untracked file.Only the tracked modification is included unless an option requests untracked content.
Include untracked files with `--include-untracked`
Use `--include-untracked` (or `-u`) when the untracked files are part of the temporary state you need to save. Git stashes those untracked files and removes them from the working directory as part of the stash operation.
git stash push --include-untracked -m "pause including new files"This is different from `.gitignore`: an untracked file can be included explicitly even though it has never been staged. Do not describe `-u` as “add everything”; it specifically extends the stash to untracked files.
Include ignored files with `--all`
Use `--all` (or `-a`) when the temporary state must also contain ignored files. This includes both untracked and ignored files and cleans them from the working directory during the stash operation.
git stash push --all -m "pause including ignored files"Quick check
Which option is required when ignored files must be included in a stash?
A repository contains an ignored build artifact that must temporarily travel with the other local changes.The ignored file is included in the stash only when `--all` is used.
Keep the staged index with `--keep-index`
`--keep-index` changes what happens to changes that are already staged: those staged changes are left intact in the index instead of being rolled back with the stash operation. Other changes can still be stashed. This is useful when you want to test or commit the staged portion while temporarily putting the remaining work aside.
git add src/feature.txt
# Keep the staged change in the index while stashing the other local changes.
git stash push --keep-index -m "stash remaining work"
git status --shortDo not confuse `--keep-index` with `--staged`. `--keep-index` controls whether already-staged changes remain in place after creating the stash. `--staged` changes what is selected for the stash itself.
Stash only staged changes with `--staged`
`--staged` tells `git stash push` to stash only the changes currently staged in the index. This is useful for separating an already-staged change from unrelated unstaged work. The staged state is placed in the stash rather than committed to the current branch.
git add docs/release-notes.md
git stash push --staged -m "save staged release notes separately"
git status --shortQuick check
What does `git stash push --staged` select?
One change is staged and another remains unstaged.The staged change is saved in the new stash while the unrelated unstaged work remains in the working tree.
Limit the stash with a pathspec
`git stash push` also accepts a pathspec after `--`. The resulting stash records modified states only for matching paths, and Git rolls back the matching paths while leaving non-matching paths intact. The `--` separates pathspecs from options and avoids ambiguity.
git stash push -m "pause only the API work" -- src/api/A path-limited stash is therefore not the same as a repository-wide stash. Before using one, identify exactly which paths should be temporarily removed from the working tree.
The state-transition checklist
Before stashing, identify four things: what is committed in `HEAD`, what is staged in the index, what is modified only in the working tree, and whether untracked or ignored files are present. Then choose the narrowest stash options that preserve exactly the temporary state you need.
# Inspect before creating the stash
git status --short
git diff --cached
git diff
# Choose one creation policy
git stash push -m "pause work"
git stash push --include-untracked -m "pause with new files"
git stash push --all -m "pause with ignored files too"
git stash push --keep-index -m "stash non-index work"
git stash push --staged -m "save staged work only"Quick Check: choose the state transition
Quick check
You have staged changes you want to leave staged while putting unstaged changes aside. Which creation option expresses that intent?
The index contains work you want to keep ready for testing or committing, while the working tree has unrelated edits.The staged index remains intact while the other eligible changes are stashed.
Practice what you learned
Use the dedicated Git code-completion exercise for this lesson.
Official references
This lesson is based only on the live official Git documentation. `git-stash` defines the stash state transition, the modern `push` command, `--include-untracked`, `--all`, `--keep-index`, `--staged`, pathspec handling, and the deprecated status of `save`. The official documentation currently describes `git stash` without a subcommand as equivalent to `git stash push`. `gitrevisions` supplies the official revision model used later when stash entries are addressed; detailed stash inspection and recovery are intentionally deferred to V462.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.