Learn how to git stash and pop specific files with step-by-step examples. Discover how to stash selected changes, manage untracked files, and apply stashes safely without affecting your entire working directory.
Table of Contents
Introduction to Git Stash and Pop
If you’ve ever been in the middle of a feature, only to be pulled away by a hot-fix on another branch, you know the pain of uncommitted changes blocking your workflow. Git stash is the escape hatch every developer needs — a command that shelves your current work so you can come back to it later without committing half-baked code.
Understanding git stash how to use it properly separates confident Git users from those who panic-commit messy WIP changes. Let’s break down the core concepts before diving into techniques.
What git stash Does
Running git stash takes all your tracked, modified files — both staged and unstaged — and saves them to a stack-based storage area. Your working directory is then restored to match the last commit (HEAD), leaving you a clean slate to switch branches or tackle a bug fix.
When Developers Should Use Stash
- Switching context to handle an urgent bug without losing progress
- Pulling in remote changes when you have local modifications that conflict
- Separating unrelated changes before committing or branching
- Testing a clean build state while preserving in-progress work
Difference Between stash, apply, and pop
| Command | What It Does | Removes From Stash List? |
|---|---|---|
git stash | Saves current changes and cleans working directory | — |
git stash apply | Re-applies stashed changes but keeps them in the stash list | ❌ No |
git stash pop | Re-applies stashed changes and removes the stash entry | ✅ Yes |
Pro Tip
apply over pop when you’re not 100% sure the stash applied cleanly. You can always drop it manually afterward — but you can’t recover a popped stash that caused conflicts.How Git Stash Works (Quick Overview)
What Gets Stashed by Default
A basic git stash captures tracked files only — both modifications to already-tracked files and changes staged via git add. What it does not capture by default:
- New untracked files (files not yet added with
git add) - Files listed in
.gitignore
Staged vs Unstaged Changes
Git tracks two “layers” of changes: the staging area (index) and the working tree. When you run git stash push, both layers are saved together by default and then cleared. If you want to preserve the staging distinction on re-apply, use the --keep-index flag.
# Save stash but keep staged changes staged
git stash push --keep-indexWhy Stashing Specific Files Is Tricky
The default git stash command is all-or-nothing. If you have three files modified and only want to stash one, you need a more surgical approach. That’s exactly what the five techniques in this guide solve — giving you precise, file-level control over your stash.
Real-World Problem
auth.js, auth.css) and tweaking a performance fix in utils.js. A teammate asks you to review their PR — but switching branches would drag your login work along. You need to stash only utils.js so your login progress stays put.Technique 1 – Stash Specific Files Using Interactive Mode
Using git stash push -p
The -p (or --patch) flag launches an interactive hunk-by-hunk session — the same powerful UI used by git add -p. You walk through each changed block and decide per-hunk whether to stash it. This gives you sub-file granularity: you can stash part of a file while leaving other changes in place.
git stash push -p
# Git will show each hunk like this:
diff --git a/src/utils.js b/src/utils.js
@@ -12,7 +12,7 @@
function debounce(fn, delay) {
- return setTimeout(fn, delay);
+ return setTimeout(fn, delay ?? 300);
}
Stash this hunk [y,n,q,a,d,e,?]?At the interactive prompt, use these keys:
| Key | Action |
|---|---|
y | Stash this hunk |
n | Skip this hunk (leave in working tree) |
q | Quit — don’t stash remaining hunks |
a | Stash this and all remaining hunks in file |
d | Skip this and all remaining hunks in file |
? | Show all options |
Step-by-Step Example
- Make changes across multiple files in your project
- Run
git stash push -pto start interactive mode - For each hunk: press
yto stash ornto keep - Git creates a stash entry with only your selected hunks
- Verify with
git diff— only un-stashed changes remain
Saved working directory and index state WIP on main: a3f9c12 Add login form
On branch main
Changes not staged for commit:
modified: src/auth.js
modified: src/auth.cssWhen to Use This Approach
Use git stash push -p when you need hunk-level precision — for instance, when a single file contains both changes you want to keep and changes you want to shelve. It’s the most granular stash method available in Git.
Limitation
-p awkwardly. Stick to the CLI for this technique.Technique 2 – Stash Specific Files by Path
Using git stash push <file>
When you know exactly which file (or files) to stash, pass the path directly to git stash push. This is the fastest, most readable approach for whole-file stashing with no prompts.
# Stash a single file
git stash push src/utils.js
# With a descriptive message (recommended)
git stash push -m "perf: debounce fix WIP" src/utils.jsExample with Multiple Files
You can pass multiple paths separated by spaces — or use glob patterns. Git will bundle all specified files into a single stash entry.
# Stash two specific files
git stash push -m "api: auth refactor" src/auth.js src/auth.css
# Stash all files in a directory
git stash push -m "api: auth refactor" src/auth/
# Stash using wildcard (shell expansion)
git stash push -m "styles: all css changes" -- "*.css"Saved working directory and index state On main: api: auth refactor
On branch main
Changes not staged for commit:
modified: src/utils.js
modified: tests/utils.test.jsLimitations to Know
- The file must be tracked by Git — if it’s new and untracked, add
-uflag - Partial file stashing is not possible here — the entire file is stashed
- Glob patterns rely on shell expansion; quote them or use
--separator to avoid misinterpretation
Note on the — separator
git stash push -- <pathspec> (with the double dash) to unambiguously tell Git that what follows are file paths, not flags. This prevents Git from misinterpreting filenames that start with a dash.Technique 3 – Apply or Pop a Specific Stash
List Stashes with git stash list
Git maintains a stack of stash entries. Each new stash goes to position stash@{0}, pushing older ones down. Before applying, always inspect what you have:
git stash liststash@{0}: On main: styles: all css changes
stash@{1}: On main: api: auth refactor
stash@{2}: WIP on feature/login: c4e1a90 Initial login scaffoldUse git stash apply specific stash
To re-apply a specific stash without removing it from the list, reference it by index. This is the key to performing a git stash apply specific stash:
# Apply the most recent stash (default)
git stash apply
# Apply a specific stash by index
git stash apply stash@{1}
# Apply the oldest stash (index 2 in this example)
git stash apply stash@{2}Use git pop specific stash
When you want to restore and remove the stash in one command, use git stash pop. The same index notation applies for a git pop specific stash:
# Pop the most recent stash
git stash pop
# Pop a specific stash entry
git stash pop stash@{1}Typical Use Case
stash@{1} — the auth refactor — without disturbing the newest or oldest stashes. Use git stash apply stash@{1} to surgically restore just that work.Difference Between Apply vs Pop
| Aspect | git stash apply | git stash pop |
|---|---|---|
| Re-applies changes | ✅ Yes | ✅ Yes |
| Removes from stash list | ❌ No | ✅ Yes |
| Safe after conflicts | ✅ Safer (stash preserved) | ⚠️ Risky if merge conflict |
| Recommended when… | Applying to multiple branches | One-shot restoration, done with stash |
Watch Out
git stash pop encounters a merge conflict, the stash entry is still deleted from the list even though the conflict wasn’t fully resolved. Always use apply when in doubt, then manually drop the stash after confirming a clean merge.Technique 4 – Include Untracked Files in Stash
Using git stash untracked files (-u)
By default, brand-new files that haven’t been staged with git add are ignored by git stash. To include these git stash untracked files in your stash, pass the -u (or --include-untracked) flag:
# Include untracked files in the stash
git stash push -u
# Include untracked + with a message (recommended)
git stash push -u -m "feat: new component scaffold"
# Include EVERYTHING (even ignored files)
git stash push -a # --allExample Scenario
Scaffolded But Not Yet Tracked
src/components/Modal.jsx and src/components/Modal.css. Neither file has been added to Git yet. Running a plain git stash leaves them behind in your working tree. With git stash push -u -m "ui: modal scaffold", both files are cleanly stashed and your directory is pristine.# Check status before stashing
git status
Changes not staged for commit:
modified: src/App.jsx
Untracked files:
src/components/Modal.jsx
src/components/Modal.css
# Stash everything including untracked
git stash push -u -m "ui: modal scaffold"
# Verify clean state
git status
nothing to commit, working tree cleanCommon Mistakes
- Forgetting
-uwhen new files exist — they stay in the working tree and cause confusion on branch switch - Using
-a(all) unintentionally — this also stashes files in.gitignorelikenode_modulesor build artifacts, which is almost never desired - Applying a
-ustash on a branch where those file paths already exist, leading to conflicts
Technique 5 – Use Stash with Message for Better Control
Using git stash with message
Without a message, stash entries are labeled with the branch name and last commit — generic and hard to distinguish when you have multiple stashes. Using git stash with message makes every entry immediately identifiable:
# Named stash — always use this
git stash push -m "fix: navbar scroll bug on mobile"
# Or using the save subcommand (older syntax, still works)
git stash save "fix: navbar scroll bug on mobile"Naming Best Practices
Treat stash messages like short commit messages. A consistent naming convention makes it easy to scan a list of stashes at a glance:
# ✅ Good — type: short description
"feat: user avatar upload WIP"
"fix: broken pagination — needs API check"
"refactor: auth module cleanup"
"chore: remove console.logs before PR"
# ❌ Bad — vague, useless in a list
"wip"
"temp"
"stash 1"
"changes"Finding Stashes Faster
With meaningful messages, you can filter the stash list using grep when your list grows long:
# List all stashes
git stash list
# Find a specific stash by keyword
git stash list | grep "avatar"
stash@{2}: On feature/profile: feat: user avatar upload WIPPro Tip — Use Branch + Ticket Number
"feat/AUTH-42: JWT refresh logic" ties work directly to tickets and makes context switching frictionless.How to View and Compare Stashes
Using git stash show diff
Before blindly applying a stash, inspect what it contains. The git stash show command gives a summary, while adding the -p flag shows the full git stash show diff — the complete patch:
# Summary of what the latest stash contains
git stash show
# Full diff for the latest stash
git stash show -p
# Full diff for a specific stash
git stash show -p stash@{2} src/auth.js | 14 ++++++++------
src/auth.css | 8 ++++++--
2 files changed, 14 insertions(+), 8 deletions(-)Inspecting Changes Before Applying
You can also compare a stash against a specific commit or branch using standard git diff syntax. This is helpful to confirm whether a stash will apply cleanly to your current branch state:
# Diff stash against current HEAD
git diff stash@{0}
# Diff stash against a specific branch
git diff stash@{0} main
# View only changed file names in a stash
git stash show --name-only stash@{1}Quick Inspection Workflow
git stash show -p stash@{n} before applying an old stash. Code evolves — what was safe to apply two weeks ago may conflict with today’s codebase.How to Clear or Remove Stashes Safely
Using git stash clear (remove)
When you’re done with your stashes — or you’ve accumulated a mountain of old WIP entries — you can nuke the entire stash list with the git stash clear (remove) command:
# ⚠️ Permanently removes ALL stash entries — no undo
git stash clearIrreversible
git stash clear is permanent and unrecoverable. Git doesn’t put stash entries in the reflog the same way commits are. Always review your stash list first with git stash list before clearing.Deleting a Single Stash
A safer approach is to delete specific entries with git stash drop. This removes one stash while preserving the rest:
# Drop the most recent stash
git stash drop
# Drop a specific stash by index
git stash drop stash@{2}
Dropped stash@{2} (c7d2e3f44a8b1c5d9e0f1a2b3c4d5e6f7a8b9c0d)Safety Tips
- Always use
git stash drop stash@{n}overgit stash clearunless you’re intentionally purging all history - Create a branch from a stash before dropping it if you’re unsure:
git stash branch <branchname> stash@{n} - Periodically audit your stash list — stashes older than a sprint cycle are usually safe to drop
Git Stash in Visual Studio and VS Code
Not all developers live in the terminal. Both Visual Studio and VS Code offer first-class support for stashing — though with slightly different workflows.
Visual Studio Stash Changes Workflow
In Visual Studio (the full IDE, not VS Code), visual studio stash changes is handled through the Git Changes pane:
Visual Studio
2. Click the ⋯ (Actions menu) at the top of the pane
3. Select Stash All or Stash Changes
4. Enter a stash message in the dialog
5. To restore: Git → Manage Stashes, select entry, click Pop or Apply
VS Code
2. Click the ⋯ menu at the top of the panel
3. Go to Stash → Stash All (or Stash for staged only)
4. Type a message and confirm
5. To restore: Stash → Apply Stash… or Pop Stash…
Visual Studio Code Stash Changes Workflow
Visual Studio Code stash changes support is built-in and requires no extensions. For more advanced workflows — like stashing specific files or using -p interactive mode — the integrated terminal (Ctrl+`) is the right tool, as the GUI only exposes whole-working-tree stashing.
# You can also use the Command Palette (Ctrl+Shift+P):
Git: Stash
Git: Stash (Include Untracked)
Git: Pop Stash
Git: Apply Stash
Git: Drop StashGUI vs CLI Comparison
| Feature | VS / VS Code GUI | CLI |
|---|---|---|
| Stash all changes | ✅ One click | ✅ git stash push -m "msg" |
| Stash specific files | ❌ Not supported | ✅ git stash push file.js |
| Interactive / patch mode | ❌ Not supported | ✅ git stash push -p |
| Apply specific stash | ✅ via list dialog | ✅ git stash apply stash@{n} |
| View stash diff | ⚠️ Limited preview | ✅ git stash show -p |
| Include untracked files | ✅ “Stash All” option | ✅ git stash push -u |
Best of Both Worlds
git stash push -p or git stash apply stash@{n}.Common Mistakes When Using Git Stash
Losing Track of Stashes
The stash stack has no expiry date. Developers stash work, get pulled onto three other things, and return weeks later to a list of WIP on main entries that are indistinguishable from each other. Always name your stashes and audit the list regularly.
Forgetting Untracked Files
New files not yet added to the index are silently left behind by a plain git stash. You switch branches, come back, and find mysterious new files cluttering your working tree. Always run git status after stashing to confirm a truly clean state — and use -u when new files are involved.
Using pop Incorrectly
- Using pop when a conflict is possible — if a conflict occurs, Git removes the stash entry but leaves your working tree in a conflicted state. Always use
applyfirst when uncertain. - Assuming pop is smarter than apply — pop is just apply + drop. It has no special conflict resolution.
- Popping onto the wrong branch — stashes aren’t branch-bound. Always confirm you’re on the right branch before popping.
Always Check Your Branch
git branch or check the branch indicator in your editor before running git stash pop. Applying a stash to the wrong branch creates confusing, hard-to-untangle history.Best Practices for Using Git Stash Efficiently
Always Use Descriptive Messages
This is the single highest-impact habit. A descriptive -m flag costs two seconds and saves minutes of confusion later. Follow a consistent format: "type: what / why".
Keep the Stash List Clean
Treat your stash like a desk surface — don’t let it accumulate. After every sprint or feature cycle, review with git stash list. Drop anything you no longer need. If a stash survived two weeks, it probably deserves to be a real branch or commit.
Prefer apply Over pop in Some Cases
Use pop only when you’re confident the stash will apply cleanly and you’re done with it. In any situation involving uncertainty — a branch you haven’t touched in a while, a stash with untracked files, or a complex merge scenario — use apply and drop manually after verifying.
Use git stash branch for Significant Work
If a stash grows beyond a small patch, promote it to a real branch. This gives the work visibility, keeps it in commit history, and makes it easier for teammates to review or collaborate on:
# Promote a stash to a branch — best practice for bigger work
git stash branch feat/modal-component stash@{0}Combine Stash with git add -p for Maximum Control
For the most precise workflow, stage exactly what you want to stash first with git add -p, then stash only the staged changes with git stash push --staged. This gives you staged + stash granularity without the interactive stash prompt.
# Stage exactly the hunks you want
git add -p
# Stash only what's staged
git stash push --staged -m "fix: targeted patch"Conclusion
Git stash is far more powerful than most developers use it for. Moving beyond git stash and git stash pop — and into specific files, named stashes, and surgical apply operations — separates developers who fight their workflow from those who flow through it.
Interactive Mode (-p)
Stash by Path
Apply/Pop Specific Stash
Untracked Files (-u)
Stash with Message
The cleanest Git workflows use git stash as a deliberate, intentional tool — not an emergency dump. Name your stashes, drop them when you’re done, and prefer apply over pop when in doubt. Your future self (and teammates) will thank you.
Your Next Step
git stash list, and clean up any unnamed stashes you find. If there are entries worth keeping, drop them onto proper branches. Start fresh with a clean, intentional stash workflow today.Also read about the difference between git merge and rebase commands with simple explanation.


