Git stash uncached: how to put away all unstaged changes?
Categories:
Git Stash Uncached: How to Put Away All Unstaged Changes

Learn how to effectively use git stash
to temporarily save only your unstaged modifications, leaving staged changes intact. This guide covers common scenarios and practical commands.
Git's stash
command is an incredibly powerful tool for temporarily shelving changes you're not ready to commit. While git stash
by default saves both staged and unstaged changes, there are scenarios where you might want to stash only the unstaged modifications, leaving your carefully prepared staged changes untouched. This article will guide you through the process of selectively stashing unstaged changes, explaining why and how to do it effectively.
Understanding Git Stash Behavior
Before diving into selective stashing, it's crucial to understand how git stash
operates by default. When you run git stash
(or git stash save
), Git takes all changes in your working directory that are tracked by Git (both staged and unstaged) and saves them onto a stack of stashes. It then reverts your working directory to the HEAD
commit, leaving it clean. Untracked files are not stashed by default, but can be included with the -u
or --include-untracked
option, or even ignored files with -a
or --all
.
flowchart TD A[Working Directory] --> B{git stash?} B -- Yes --> C[Staged Changes] B -- Yes --> D[Unstaged Changes] C --> E[Stash Stack] D --> E[Stash Stack] E --> F[Working Directory Clean]
Default Git Stash Behavior
The Need for Selective Stashing
Why would you want to stash only unstaged changes? Consider these common situations:
- Interruption during staging: You've carefully staged a set of changes for a specific commit, but then an urgent bug fix or context switch comes up. You want to save your current work-in-progress (the unstaged changes) without losing your staged changes.
- Refining a commit: You've staged some changes, but then made additional experimental modifications that you're not sure about. You want to stash these new, unstaged changes to focus on committing only the staged ones.
- Keeping a clean staging area: You prefer to keep your staging area pristine for a specific commit, but need to temporarily remove other modifications from your working directory.
How to Stash Only Unstaged Changes
The trick to stashing only unstaged changes involves temporarily staging all your changes, then stashing, and finally unstaging the original changes. Here's the step-by-step process:
1. Stage all current changes
First, stage all changes in your working directory, including both those you originally intended to stage and the new unstaged ones. This ensures that git stash
will capture everything.
2. Stash all changes
Now, perform a regular git stash
. Since all changes are staged, this will stash everything, effectively cleaning your working directory.
3. Unstage the original changes
After stashing, your working directory is clean. The next step is to bring back the changes you originally had staged. You can do this by applying the stash, but immediately resetting the index to the HEAD
commit. This will unstage the changes that were part of the stash, leaving them as unstaged modifications in your working directory.
4. Re-apply the stash (optional)
If you want to bring back the unstaged changes you just stashed, you can now apply the stash. Since your original staged changes are now unstaged, applying the stash will reintroduce the other changes as unstaged, effectively achieving your goal.
# 1. Stage all current changes (including those you want to stash)
git add .
# 2. Stash all changes
git stash save "Temporarily stashing all changes"
# 3. Unstage the original changes (the ones you wanted to keep staged)
git reset HEAD^
# 4. Now, your original staged changes are unstaged.
# If you want to bring back the *other* changes you stashed, apply the stash:
git stash pop
Commands to selectively stash unstaged changes
git stash --keep-index
(or git stash -k
). This command stashes all changes that are not currently staged, leaving your staged changes in the index. This is often the most straightforward solution for the problem described.# Stash only unstaged changes, leaving staged changes intact
git stash --keep-index
Using git stash --keep-index
for direct unstaged stashing
flowchart TD A[Working Directory] --> B{Staged Changes} A --> C{Unstaged Changes} B -- Kept --> D[Staging Area] C -- Stashed --> E[Stash Stack] D --> F[Ready for Commit]
Git Stash with --keep-index
Behavior
git stash --keep-index
will not stash untracked files. If you need to stash untracked files along with your unstaged modifications, you'll need to add them to the index first (e.g., git add .
) or use git stash -u
(which stashes untracked files but also staged and unstaged changes).