You’re halfway through a feature, your code doesn’t compile, and someone needs you on another branch right now. So what does Git stash do in this situation? It saves your uncommitted changes to a hidden stack and gives you a clean working directory, without creating a single commit.
Most developers know git add, git commit, and git push. But stash is the command that keeps your workflow from falling apart when real work gets interrupted.
This guide covers how git stash works under the hood, the full command syntax, how to retrieve and manage multiple stashes, common pitfalls, and how stash compares to alternatives like git worktree and WIP commits.
What Is Git Stash

Git stash is a command that temporarily saves uncommitted changes in your working directory without creating a commit on your current branch. It takes everything you’ve modified (both staged and unstaged files) and stores it in a hidden stack structure tied to your local repository.
Think of it as a clipboard for your code. You copy your in-progress work, set it aside, and your working directory goes back to matching the last commit.
Linus Torvalds created Git in 2005 to manage Linux kernel development. The stash feature arrived later with Git version 1.5.3 in 2007, filling a gap that developers kept running into: needing to pause work without polluting the commit history.
Git adoption among developers has climbed from 87.1% in 2016 to 93.87% in 2025, according to Stack Overflow Developer Survey data. The version control systems market was valued at USD 1.03 billion in 2024, per Grand View Research, and is growing at an 18.6% CAGR through 2030.
That growth means more developers rely on Git daily. And stash is one of those commands that separates someone who just knows git add, git commit, git push from someone who actually understands their workflow.
The stash operates as a last-in, first-out (LIFO) stack. Every time you stash changes, they get pushed onto the top. When you retrieve them, the most recent stash comes off first. Simple concept, but it solves a real problem that hits you multiple times a week if you’re on any active team.
How Git Stash Works Under the Hood

Running git stash does more than hide your files somewhere. Git actually creates a special commit object behind the scenes.
That commit object references three things:
- The state of your working directory (all modified tracked files)
- The state of your staging index (anything you’ve already run
git addon) - The HEAD commit at the time you stashed
Stash entries live in .git/refs/stash and are managed through Git’s reflog system. Each entry gets a reference like stash@{0}, stash@{1}, and so on.
After stashing, your working directory resets to match HEAD. That’s the whole point. You get a clean slate to do whatever you need to do, whether that’s switching branches, pulling remote changes, or handling a hotfix.
Staged vs. Unstaged vs. Untracked
Staged changes: files you’ve already added to the index with git add. Git stash grabs these by default.
Unstaged changes: modifications to tracked files that haven’t been staged yet. Also grabbed by default.
Untracked files: brand new files Git doesn’t know about. These are not included unless you pass the --include-untracked flag. Took me way too long to figure that out the first time.
One thing that catches people: by default, when you apply a stash, Git doesn’t preserve the distinction between what was staged and what wasn’t. Everything comes back as unstaged modifications. You need the --index flag on apply to restore that separation.
Git Stash Command Syntax and Variations

The basic git stash command is actually shorthand for git stash push. But there’s a lot more you can do with it.
| Command | What It Does | When to Use It |
|---|---|---|
git stash | Stashes all staged and unstaged changes | Quick context switch |
git stash push -m "message" | Stashes with a descriptive label | When managing multiple stashes |
git stash --include-untracked | Also stashes new untracked files | When new files need saving too |
git stash --all | Stashes everything, including ignored files | Full directory cleanup |
git stash -p | Interactive partial stash | When you want to stash specific changes only |
git stash --keep-index | Stashes only unstaged changes | Testing staged work in isolation |
The -p flag is underrated. It lets you pick exactly which changes to stash, hunk by hunk. Useful when you’ve been working on two separate things in the same file and only want to set aside one of them.
The --keep-index option is great for a specific workflow: you’ve staged some changes and want to test just those before committing. Stash the unstaged stuff, run your tests, then bring it back.
Git Stash Push vs. the Deprecated Git Stash Save
If you’ve been reading older Stack Overflow answers or tutorials, you’ve probably seen git stash save "message" everywhere. That syntax was deprecated in Git 2.16.
The replacement is git stash push -m "message". The key difference? push supports pathspec arguments, meaning you can stash changes from specific files only:
git stash push -m "just the CSS" -- styles.css
save couldn’t do that. It was all or nothing.
Both still work in current Git versions, but save won’t get new features. If you’re writing scripts or technical documentation, use push.
How to Retrieve Stashed Changes

Stashing changes is only half the story. Getting them back is where most of the confusion happens.
Two commands handle retrieval: git stash pop and git stash apply. They do almost the same thing, but with one critical difference that matters more than you’d expect.
Git Stash Pop vs. Git Stash Apply
git stash pop applies the most recent stash to your working directory and deletes it from the stash stack. One action, stash is gone.
git stash apply applies the stash but keeps it in the stack. The stash entry stays available if you need it again.
| Behavior | git stash pop | git stash apply |
|---|---|---|
| Applies changes | Yes | Yes |
| Removes from stack | Yes (on success) | No |
| On merge conflict | Stash is kept | Stash is kept |
| Safer for risky merges | No | Yes |
Here’s something that trips people up: if git stash pop hits a merge conflict, the stash is not deleted. Git keeps it because the apply didn’t fully succeed. You have to resolve the merge conflict manually, then run git stash drop yourself.
Research on open source projects found that roughly 19.32% of merges result in conflicts, according to a study analyzing 556,911 commits across 143 projects. That number goes up significantly in active team environments. Using apply instead of pop gives you a safety net when you’re not sure if your stashed changes will play nice with what’s currently in the branch.
Applying a Specific Stash
Don’t always need the most recent one. Target a specific stash by its index:
git stash apply stash@{2}
Or the shorthand that works in newer Git versions: git stash apply 2
Check what’s in a stash before applying it with git stash show stash@{2}. Add -p for the full diff. Your mileage may vary on whether you remember what each numbered stash contains, which is exactly why labeling them with -m matters.
Managing Multiple Stashes

One stash is easy. Five stashes with no labels? That’s where things get messy fast.
git stash list shows everything currently stored:
“ stash@{0}: WIP on feature-auth: 3a2b1c4 Add login form stash@{1}: WIP on main: 7d8e9f0 Update README stash@{2}: On feature-auth: fix header alignment `
That third entry has a custom message because someone used git stash push -m “fix header alignment”. The first two just got the default "WIP on branch" label. Guess which one is easier to identify three days later.
Cleaning Up Old Stashes
Drop a single stash: git stash drop stash@{1} removes just that entry and re-indexes the rest.
Clear everything: git stash clear wipes all stashes. No confirmation prompt, no undo. Gone.
GitHub now hosts over 180 million developers and more than 630 million repositories, according to the Octoverse 2025 report. With that many people collaborating on code, orphaned stash entries pile up quickly on local machines. It’s a good habit to run git stash list once a week and clean out anything you don't need.
By the way, if you ever stash something and then realize you want it on a completely different branch, there’s a command for that: git stash branch new-branch-name. It creates a new branch from the commit where the stash was originally made, applies the stash, and drops it. Cleaner than trying to apply an old stash onto a branch that's diverged significantly.
Common Scenarios Where Git Stash Is Useful

Knowing the commands is one thing. Knowing when to reach for stash is where it actually saves you time.
Switching Branches Mid-Task
You’re halfway through a feature. A teammate pings you to review something on another branch. You haven’t committed yet because the code doesn’t compile.
Without stash, your options are bad: make a messy WIP commit, or lose your changes. With stash, you save everything, switch to the other branch, do the review, come back, and pop your stash. Thirty seconds of overhead instead of five minutes of cleanup.
Pulling Remote Changes on a Dirty Directory
You try git pull and Git refuses because your working directory has uncommitted changes that conflict with incoming updates.
The fix is three commands:
- git stash
- git pull
- git stash pop
This is probably the single most common use case for git stash in real software development teams. The official Git documentation even lists this exact pattern as its first example.
Testing Against a Clean Working Tree
Sometimes you need to confirm whether a bug exists in the committed code or if it’s something your local changes introduced.
Stash your work, run the tests, check the results. Then pop the stash and keep going. Quick, non-destructive, and way faster than checking out a different commit.
Moving Changes to the Wrong Branch
Started coding on main when you should have been on a feature branch. Classic mistake.
Stash the changes, create a new branch (or switch to the right one), then pop. No commits on main, no tangled history. The whole source control management process stays clean.
Emergency Hotfixes During Active Development
A production bug lands on your desk. Your current branch is mid-refactor with half-working code everywhere.
Stash. Switch to the release branch. Fix the bug. Commit and push. Switch back. Pop. Continue where you left off.
Hutte research found that 85% of developers say Git has improved collaboration within their teams. Stash is a big part of why. It lets you handle interruptions without derailing your work or polluting the codebase with throwaway commits.
Git Stash vs. Other Ways to Save Work in Progress

Git stash isn’t the only option for saving uncommitted work. Several alternatives exist, and each fits a different situation. Picking the wrong one wastes time. Picking the right one keeps your git workflow clean.
Git Stash vs. a Temporary WIP Commit
The “commit everything with a WIP message” approach is probably the most common alternative to stashing. It works, but it has tradeoffs.
| Factor | Git Stash | WIP Commit |
|---|---|---|
| History pollution | None (stash is hidden) | Yes, unless you amend or squash later |
| Shareable with team | No (local only) | Yes (can be pushed) |
| Risk of forgetting | High (unlabeled stashes are easy to overlook) | Low (visible in commit history) |
| CI/CD impact | None | May trigger pipelines |
If your team uses a build pipeline that triggers on every commit, a careless WIP commit on a shared branch can kick off unnecessary builds. Stash avoids that entirely.
Git Stash vs. Git Worktree
Git worktree, introduced in Git 2.5, takes a completely different approach. Instead of hiding your changes, it lets you check out a second branch in a separate directory while keeping your current work untouched.
No stashing required. No context switching overhead. Both branches exist simultaneously on disk.
The stash-switch-unstash loop works for quick interruptions (a five-minute review, a fast pull). But when you’re juggling two active tasks over hours or days, worktree is the better pick. You can literally open two editor windows and work on both branches at the same time.
The downside? Worktrees create extra directories, and each one needs its own dependency install if you’re working with something like node_modules. For quick context switches, that's overkill.
Git Stash vs. Discarding Changes
Key difference: git checkout — . or git restore . permanently deletes your uncommitted changes. There's no getting them back.
Stash preserves everything. If you’re even slightly unsure whether you’ll need those changes again, stash first. The worst that happens is you drop it later.
Limitations and Pitfalls of Git Stash
Stash is useful. It’s also got some sharp edges that aren’t obvious until you hit them.
Stashes Are Local Only
Your stashes don’t travel with git push or git pull. They exist only in your local repository, tied to your machine.
If you’re working on a remote repository with teammates, nobody else can see your stashed changes. Lose your local clone, lose your stashes. If the changes matter enough to survive a laptop crash, commit them to a branch instead.
Merge Conflicts on Apply
You stash some changes on Monday. By Thursday, the branch has moved forward with new commits from the team. When you pop the stash, there’s a good chance the changes collide with what’s been committed since.
A study of 143 open source projects found that about 19% of all merges produce conflicts. Stash applies aren’t immune. And resolving a stash conflict is trickier than a regular merge conflict because there’s no clear “theirs” branch to reference.
Stash Rot
This one is a behavioral problem, not a technical one.
Developers stash something with good intentions, switch to another task, and simply forget the stash exists. Weeks pass. The stash becomes irrelevant because the branch it was meant for has already been merged or rewritten.
GitHub’s Octoverse 2025 report shows developers pushed nearly 1 billion commits in a single year, a 25% increase over the prior year. With that much activity, stashes from even a few days ago can become completely stale. Label your stashes with -m and clean them up weekly.
The Staged/Unstaged Distinction Gets Lost
Default behavior: when you apply a stash, everything comes back as unstaged modifications, even files you had carefully staged before stashing.
You need the –index flag to preserve that distinction: git stash apply –index. Most people don't know this flag exists, which leads to confusion when their carefully organized staging area gets flattened.
Unnamed Stashes Become Unmanageable
Three stashes? Fine. Ten stashes with default “WIP on main” labels? Good luck remembering which is which.
The fix is simple but requires discipline: always use git stash push -m “description”. If you're already in the habit of writing decent commit messages, apply the same thinking to stash labels.
Git Stash in GUI Clients and IDE Integrations

Not every developer lives in the terminal. Most modern IDEs and Git clients have stash support built in, though the level of integration varies quite a bit.
VS Code Source Control Panel
Visual Studio Code has stash management directly in its Source Control view. The workflow goes through the ellipsis menu (“…”) at the top of the panel.
Available stash actions in VS Code:
- Stash (tracked changes only) or Stash Including Untracked
- Apply Latest Stash vs. Apply Stash (pick from list)
- Pop Latest Stash vs. Pop Stash
- Drop Stash or Drop All Stashes
VS Code also supports connecting to GitHub for remote operations, and its stash container shows stored entries visually. Clean interface, but you won’t find flags like –keep-index or -p (partial stash) in the GUI. Those still require the terminal.
JetBrains IDEs: Shelve vs. Stash
IntelliJ IDEA, WebStorm, PyCharm, and the rest of the JetBrains family support both git stash and their own proprietary feature called Shelve.
| Feature | Git Stash (in JetBrains) | JetBrains Shelve |
|---|---|---|
| Generated by | Git itself | The IDE |
| Usable outside IDE | Yes | Not without extra steps |
| Partial file selection | No (whole working directory) | Yes (individual files/changelists) |
| Cross-repo changelists | No | Yes |
Shelve stores patches in the .idea/shelf directory. That's IDE-specific, meaning it won't sync across machines unless you share that folder. Most teams exclude .idea from version control entirely.
JetBrains IDEs also let you combine the Stash and Shelf tabs into a single view, which reduces confusion when you’ve used both features on the same project.
GitKraken and Sourcetree
These standalone Git clients take different approaches to stash visibility.
GitKraken shows stashes as entries in the commit graph, making it obvious where in the timeline each stash was created. You can right-click to pop, apply, or delete. It’s visual and quick.
Sourcetree (by Atlassian) has a dedicated stash section in its left sidebar. You can stash with a message, view the diff of any stash entry, and apply to whatever branch is currently checked out.
Neither tool exposes every flag that the command line offers. The –keep-index flag, the -p interactive mode, and the –all option (for ignored files) are typically missing from GUI interfaces. If your workflow depends on partial stashing or testing staged changes in isolation, you'll need the terminal for that.
When the GUI Hides Too Much
The biggest risk with GUI stash tools is that they abstract away the –include-untracked flag. Some clients default to including untracked files, others don't. And the behavior isn't always obvious from the interface.
I’ve seen developers stash through their IDE, switch branches, and then wonder why brand new files they created are still sitting in their working directory. The GUI stashed tracked changes but left the new files behind because untracked wasn’t selected.
If you’re relying on a GUI for source control, take five minutes to check what your tool actually does when you hit “Stash.” Open the terminal and run git stash list and git status after stashing to confirm the behavior matches your expectations.
FAQ on What Does Git Stash Do
What does git stash do exactly?
Git stash temporarily saves your uncommitted changes (both staged and unstaged) to a hidden stack, then resets your working directory to match the last commit. Your modifications aren’t lost. They’re stored locally until you retrieve them with pop or apply.
Does git stash save untracked files?
Not by default. Running git stash only saves tracked file modifications. To include new untracked files, add the –include-untracked flag. Use –all if you also need to stash files listed in your .gitignore.
What is the difference between git stash pop and git stash apply?
Pop applies the most recent stash and removes it from the stack. Apply restores the changes but keeps the stash entry intact. Use apply when you’re unsure about merge conflicts, since it gives you a safety net.
Can I stash changes on one branch and apply them to another?
Yes. Stashes aren’t tied to a specific branch. You can stash on main, switch to a feature branch, and pop the stash there. This is a common way to move uncommitted work to the correct branch.
How do I see what’s in my stash?
Run git stash list to view all stored entries. To see the actual file changes inside a specific stash, use git stash show -p stash@{0}. The -p flag gives you the full diff, not just filenames.
Does git stash create a commit?
Technically, yes. Git creates a special commit object internally to store your stashed changes. But this commit doesn’t appear in your branch history or git log. It lives in .git/refs/stash and the reflog.
What happens if git stash pop causes a conflict?
Git will partially apply what it can and mark conflicting files. The stash entry is not deleted when pop fails due to conflicts. You’ll need to resolve the conflicts manually, then run git stash drop to remove the stash yourself.
Is git stash save the same as git stash push?
They’re similar, but save was deprecated in Git 2.16. The push command replaced it and added support for pathspec arguments, meaning you can stash specific files only. Use push going forward.
Can I name or label a stash?
Yes. Use git stash push -m “your description” to add a message. This makes stashes far easier to identify when you run git stash list. Without labels, stash entries just show a generic "WIP on branch" message.
How do I delete all stashes at once?
Run git stash clear. This wipes every stash entry from the stack permanently. There's no undo and no confirmation prompt. To remove just one entry, use git stash drop stash@{n} with the specific index number.
Conclusion
Understanding what does Git stash do gives you a practical tool for handling the interruptions that hit every developer. It keeps your working directory clean while preserving uncommitted changes in a local stack you can retrieve anytime.
The command itself is simple. The real skill is knowing when to reach for stash versus a WIP commit, a git checkout to a new worktree, or a proper branch.
Label your stashes with -m. Clean them up regularly. Use apply over pop when merge conflicts are likely.
Git stash fits into a larger development process where good habits compound. Small commands, used well, keep your repository history clean and your configuration management tight.
Master the basics first. Then explore flags like –keep-index and –include-untracked` as your workflow demands them.
- CSS Cheat Sheet - May 18, 2026
- How to Set Up VSCode for Python Development - May 16, 2026
- How Using One Platform Can Simplify Order Fulfillment - May 15, 2026



