Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

Git Stashing

Temporarily save local working-tree and index state with precise control over tracked, untracked, ignored, staged, and path-limited changes.

Levels: Intermediate ~50 min read

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.

bash
git status --short
git stash push -m "pause unfinished work"
git status --short

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

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

bash
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 untracked

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

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

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

bash
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 --short

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

bash
git add docs/release-notes.md
git stash push --staged -m "save staged release notes separately"
git status --short

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

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

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

Was this page helpful?

Mark this learning resource complete to track your learning progress.