Git Stashing and Temporary Work
One of the most practical yet underutilized features in Git is stashing. Whether you need to switch branches mid-task, save work-in-progress changes without committing, or temporarily set aside modifications to deal with an urgent issue, stashing provides a powerful solution. This guide covers everything you need to master Git stash in real-world development scenarios.
What Is Git Stash?
Git stash allows you to temporarily save changes in your working directory and index without creating a commit. When you stash changes, Git creates a special commit object that stores your modifications and reverts your working directory to the last commit state. This is invaluable when you need to switch contexts quickly, handle urgent fixes, or clean up your workspace without losing work.
Unlike commits, stashed changes are not part of your repository history. They're stored locally in a stack structure, meaning you can have multiple stashes and apply them selectively. This makes stashing ideal for temporary work that you don't want to pollute your commit history.
Common Stashing Scenarios
Understanding when to use stash is as important as knowing how. Here are the most common real-world situations where stashing saves time and prevents mistakes:
Scenario 1: Urgent Bug Fix Required
You're in the middle of implementing a feature with several modified files. A critical production bug is reported. You can't commit incomplete work, but you need to switch branches immediately. Stash your changes, switch to the production fix branch, apply the fix, and return to your feature branch to unstash and continue working.
Scenario 2: Branch Switch Without Conflicts
Git prevents switching branches if your working directory has uncommitted changes that would conflict with the target branch. Stashing clears your working directory, allowing you to switch branches safely, then unstash on the new branch once you've sorted things out.
Scenario 3: Experimental Work Not Ready for Commit
You're exploring different approaches to a problem, making multiple experimental changes. You want to save your progress without committing incomplete or messy code. Stash lets you preserve the state while keeping your commit history clean.
Scenario 4: Code Review Feedback Integration
You've submitted code for review and received feedback requiring changes. You have new modifications in progress but reviewers need specific changes applied first. Stash your current work, make the requested changes, commit them, then unstash and continue with your original modifications.
Basic Stashing Operations
Let's explore the fundamental stashing commands you'll use daily:
Stashing Your Changes
The simplest stash command saves all tracked file modifications and staged changes:
git stash
This creates a stash entry and reverts your working directory to the last commit. For clarity, it's better to provide a descriptive message:
git stash save "work on login feature"
Or the newer syntax (Git 2.13+):
git stash push -m "work on login feature"
Stashing Untracked Files
By default, git stash only saves tracked files. To include untracked files (new files not yet added to the index), use the -u flag:
git stash -u -m "save with untracked files"
Stashing Specific Files
You can stash changes to specific files while leaving others modified:
git stash push -m "partial stash" path/to/file.js another/file.py
This stashes only the specified files, leaving other modifications untouched.
Viewing Your Stash Stack
Git maintains a stack of stashes. List all stashed changes with:
git stash list
This displays output like:
stash@{0}: work on login feature
stash@{1}: fix validation bug
stash@{2}: experimental layout changes
The most recent stash is at index 0. Use these identifiers to reference specific stashes.
Inspecting Stash Contents
Before applying a stash, check what changes it contains:
git stash show -p stash@{0}
The -p flag shows the full diff. Without it, you get a summary of files changed:
git stash show stash@{0}
Applying and Removing Stashes
Once you've stashed changes, you'll eventually want to bring them back into your working directory. Git offers several ways to do this with different behaviors.
Applying a Stash
Apply the most recent stash without removing it:
git stash apply
The stash remains in the stack, so you can apply it to multiple branches. Apply a specific stash by reference:
git stash apply stash@{2}
Popping a Stash
Apply a stash and automatically remove it from the stack:
git stash pop
This combines apply and drop into one operation. It's the most common workflow: stash, do other work, then pop to restore.
Handling Merge Conflicts During Apply
When applying a stash, conflicts can occur if the code has changed since the stash was created. Git marks the conflicts, and you resolve them normally. After resolving, your working directory contains the merged result with the stash removed from the stack (if you used pop).
Dropping Stashes
Delete a stash without applying it:
git stash drop stash@{1}
Delete all stashes:
git stash clear
Be careful with clear—it removes all stashes permanently with no recovery.
Advanced Stashing Techniques
Beyond basic stashing, there are powerful techniques for complex workflows and team-based development.
Creating a Branch from a Stash
If you stashed work and want to develop it further without affecting your current branch, create a new branch directly from the stash:
git stash branch feature-experiment stash@{0}
This creates a new branch, applies the stash, and removes it from the stack. It's perfect for exploratory work that might become a long-lived feature.
Stashing Only Staged Changes
Sometimes you stage specific changes for commit but want to stash them temporarily:
git stash push --staged -m "staged changes for later"
This stashes only staged changes, leaving unstaged modifications in your working directory.
Partial Stashing with Interactive Selection
For fine-grained control, stash only specific hunks of code:
git stash push -p -m "stash selected hunks"
The -p flag invokes interactive mode, where you approve or reject each hunk. This is powerful when a single file has both stashable and non-stashable changes.
Stashing Keep Index
Keep staged changes in your working directory while stashing unstaged modifications:
git stash push --keep-index -m "stash unstaged only"
This is useful when you've staged code for commit but want to temporarily save other modifications without disrupting the staged content.
Real-World Workflow Examples
Understanding stashing in isolation is one thing; applying it to realistic development scenarios is another. Here are detailed examples of how stashing integrates into professional workflows.
Example 1: Interrupt and Handle Priority Bug
You're implementing a new authentication system with multiple modified files. A critical security vulnerability is discovered in production:
git status
# Modified: auth/login.js, auth/session.js, auth/token.js
git stash push -m "work on new auth system" -u
# Working directory clean, ready for branch switch
git checkout hotfix/security-vulnerability
# Make security fix
git add .
git commit -m "fix: patch authentication vulnerability"
git push
git checkout feature/new-auth
git stash pop
# Continue implementing new system with previous changes restored
Example 2: Clean Up Commit History Before Push
You've been working on a feature but made some experimental changes you don't want to commit. Before pushing to remote:
git status
# Modified files include both production code and experimental changes
git stash push -m "experimental ui variations"
# Leaves only finalized code in working directory
git add .
git commit -m "implement feature X"
git push
git stash pop
# Continue experimenting locally without affecting remote history
Example 3: Managing Multiple Feature Branches
You're working on feature A but need to quickly review and fix issues in feature B. Rather than committing incomplete work:
git stash -m "feature A work in progress"
git checkout feature-b-review
# Review and fix feature B issues
git push
git checkout feature-a
git stash pop
# Resume with previous context restored
Avoiding Common Stashing Mistakes
While stashing is powerful, misuse can create confusion. Here are common pitfalls and how to avoid them:
Mistake 1: Forgetting About Stashed Work
Stashed changes can pile up and be forgotten. Regularly review your stash stack:
git stash list
Clean up old, unnecessary stashes to avoid confusion. Better yet, adopt a discipline of applying or dropping stashes within the same work session.
Mistake 2: Losing Track of Which Stash Contains What
Always use descriptive messages when stashing:
git stash push -m "specific description of what's stashed"
This makes it easy to identify the correct stash when reviewing your stack later.
Mistake 3: Stashing When You Should Commit
If changes represent meaningful work, commit them instead of stashing. Commits preserve history; stashes are temporary. Use stashing only for genuine temporary work.
Mistake 4: Applying Stash to Wrong Branch
Always verify your current branch before applying a stash:
git status
git branch -v
# Then apply stash to correct branch
Stashing in Team Environments
Teams with shared repositories can apply stashing principles to improve collaboration and reduce merge conflicts:
Pre-Commit Cleanup
Before committing and pushing, stash experimental or non-essential changes to keep the shared history clean and focused on production changes.
Code Review Integration
When reviewers request changes, stash your current experimental work, apply the requested fixes, commit, and push. Then unstash to continue with original modifications.
Pull and Rebase Safety
Before pulling remote changes, stash local modifications to avoid conflicts. After pulling and rebasing, pop your stash and resolve any new conflicts locally.
Stashing vs. Other Git Features
Understanding when to use stashing versus related Git features is important for effective version control:
Stash vs. Commit
Commits are permanent history entries meant for meaningful milestones. Stashing is temporary, ideal for work-in-progress that's not ready for history. If you have code you might want to reference later, commit it. If it's truly temporary, stash it.
Stash vs. Branch
Branching creates isolated development lines. Stashing saves changes without branching. Use branches for major feature development; use stashing for minor temporary work or context switching.
Stash vs. Tags
Tags mark specific commits as important (releases, milestones). Stashes are temporary change containers. They serve entirely different purposes in your workflow.
Integrating Stashing with Modern Development Tools
Many modern IDEs and Git GUIs provide visual interfaces for stashing, making it even more accessible. VS Code, GitKraken, and Tower all offer one-click stashing. However, understanding the underlying commands ensures you can stash effectively from any environment, including remote servers and CI/CD pipelines.
For developers using AI-assisted development tools, stashing becomes especially valuable. You can stash your current work, ask AI tools to generate alternative approaches, stash those experiments, and compare different solutions through strategic use of multiple stashes.
Key Takeaways on Git Stashing
Git stashing is an essential skill that separates novice developers from professionals who work efficiently with version control. The ability to manage temporary work, handle context switches, and keep your commit history clean transforms your development workflow. Master stashing through regular use in your daily work, and you'll find it indispensable for handling the unexpected interruptions and parallel demands of modern software development.
Pro Tip
Combine stashing with Git aliases for maximum efficiency. Create aliases like git config --global alias.stashs 'stash show -p' and git config --global alias.stashls 'stash list' to speed up common stashing operations. Powerful Git workflows multiply productivity over months and years of development.