Git Stash: Save and Restore Uncommitted Changes
Git stash allows you to store uncommitted changes and reapply them later.
Stashing Changes in Git
Git stash is a practical feature that solves a common problem in every developer's workflow. You are in the middle of working on a new feature, with changes scattered across several files, when suddenly a critical bug report arrives. You need to switch to another branch and fix it immediately, but your current work is not ready to commit. What do you do? This is exactly where git stash becomes invaluable.
Instead of forcing you to create incomplete or messy commits that clutter your history, Git stash stores your changes safely in a temporary area and restores your working directory to a clean state. Later, when you are ready, you can reapply those changes exactly as they were. This gives you the flexibility to switch contexts without losing progress and without compromising your commit history.
Why Use Git Stash
Developers frequently face situations where they need to quickly switch context without losing ongoing work. Committing unfinished code is not a good practice, especially when following structured workflows where each commit should represent a complete, logical unit of work. Git stash provides a clean and safe alternative that keeps your history meaningful.
- Switch branches quickly: Save your current changes and move to another branch without dealing with conflicts or forced commits.
- Avoid unnecessary commits: Keep incomplete work out of your commit history, maintaining a clean and professional project timeline.
- Work on urgent fixes: Temporarily pause current work to handle high priority tasks without losing your place.
- Experiment safely: Try out different approaches or test ideas without committing them permanently to the repository.
- Pull updates smoothly: Stash local changes before pulling new updates from a remote repository to avoid merge conflicts.
This approach fits well within structured development practices discussed in Git workflows and helps maintain a clean and meaningful project history.
How Git Stash Works
When you run git stash, Git takes all your modified tracked files and saves them in a special stack-like structure called the stash. Your working directory is then reset to match the state of the last commit. This allows you to switch branches, pull updates, or perform other operations without interference from your unfinished changes.
By default, Git stash only saves changes in tracked files. Untracked files and ignored files are not included unless you explicitly tell Git to include them. Each stash entry is stored with an identifier, and you can save multiple stashes and manage them independently. The stash stack operates like a LIFO (last in, first out) structure, where the most recent stash is always at the top.
# Save current changes (tracked files only)
git stash
# View all stashed entries with their identifiers
git stash list
# Apply the latest stash without removing it
git stash apply
# Apply and remove the latest stash in one step
git stash pop
# Apply a specific stash by its identifier
git stash apply stash@{1}
# Delete a specific stash
git stash drop stash@{1}
# Delete all stashes
git stash clear
Stashing with Messages
By default, stash entries are saved with a generic message that only indicates which commit they were based on. When you have multiple stashes, this can make it difficult to identify which stash contains which work. Adding a custom message when creating a stash solves this problem and makes your stash list much more useful.
# Save stash with a custom message
git stash push -m "Work in progress on login form validation"
# You can also use the older syntax
git stash save "Work in progress on login form validation"
Adding messages makes it easier to manage multiple stashes, especially when you are working on different features or tasks simultaneously. This practice aligns with maintaining clarity in your workflow as discussed in Git best practices.
Including Untracked and Ignored Files
By default, Git stash only saves changes to tracked files. Untracked files remain in your working directory, and ignored files are completely untouched. In some cases, however, you may want to stash these files as well, especially when they are part of your current work.
# Include untracked files (new files not yet added to Git)
git stash -u
git stash --include-untracked
# Include both untracked and ignored files
git stash -a
git stash --all
Use these options carefully, as stashing ignored files may include build artifacts, dependency folders, or other large files that you normally exclude using .gitignore. The -a option can create much larger stashes and is best used only when absolutely necessary.
Applying Specific Stashes
When you have multiple stash entries, you may want to apply a specific one instead of the most recent. Each stash is identified by an index such as stash@{0} (the most recent), stash@{1} (the second most recent), and so on. You can use these identifiers to apply or drop specific stashes.
# View all stashes with their indexes
git stash list
# Output example:
# stash@{0}: On main: WIP on login validation
# stash@{1}: On feature/auth: Work in progress on password reset
# stash@{2}: On main: Testing new API integration
# Apply a specific stash without removing it
git stash apply stash@{1}
# Apply and remove a specific stash
git stash pop stash@{1}
# Remove a specific stash without applying it
git stash drop stash@{2}
This flexibility allows you to manage multiple pieces of temporary work efficiently without confusion. You can have stashes for different branches, different features, or different experiments, all stored separately and applied when needed.
Stash vs Commit
A common question is when to use stash instead of making a commit. While both save changes, they serve very different purposes and should be used appropriately. Understanding this distinction is key to maintaining a clean repository.
- Use stash when: Changes are temporary, incomplete, or not ready to be part of project history. You need to switch contexts quickly without creating permanent records. The work may be experimental or may be discarded entirely.
- Use commit when: Changes are meaningful, complete, and should be permanently recorded in the repository. The work represents a logical unit of progress that you want to share, document, or use as a foundation for further work.
Committing creates a permanent record in your repository that is shared with others when pushed. Stashing is temporary and local to your machine, never shared with other developers. Understanding this distinction is essential when following the basic Git workflow.
Common Use Cases for Git Stash
Git stash shines in real development scenarios where flexibility and speed are important. Here are some common situations where stash proves invaluable.
- Switching tasks: You are working on a feature but need to switch to another branch for a quick fix. Stash your current work, switch branches, fix the issue, then come back and pop the stash to continue.
- Fixing production bugs: An urgent bug appears in production. Stash your current work, switch to the main branch, create a hotfix branch, fix the bug, and deploy. Later, pop your stash and resume your original work.
- Pulling updates: You try to pull the latest changes from the remote but Git refuses because you have local modifications. Stash your changes, pull the updates, then pop the stash and resolve any conflicts that arise.
- Testing ideas: You want to try a different approach to a problem without committing your current approach. Stash your current work, try the new approach, then decide which approach to keep. The stashed work remains available if you need it.
- Code review interruptions: You are deep in development when a colleague asks for help reviewing code. Stash your changes, review their code, then pop the stash and continue.
These scenarios are common in team environments where developers frequently interact with fetching and pulling changes from shared repositories and need to respond to changing priorities.
Handling Conflicts When Applying Stashes
When you apply or pop a stash, conflicts can occur if the files you stashed have changed in the branch you are applying to. This is especially common when you stash changes, switch branches, and the target branch has moved forward with new commits.
# Apply the stash, which may cause conflicts
git stash pop
# Git will show conflict markers in affected files
# Edit the files to resolve conflicts
# Stage resolved files
git add filename.txt
# The stash is not automatically removed if there were conflicts
# After resolving, you may want to drop it
git stash drop
# Alternatively, create a new branch from the stash
git stash branch new-branch stash@{0}
One useful trick is the git stash branch command, which creates a new branch starting from the commit where the stash was created and then applies the stash to it. This is helpful when you have conflicts and want to resolve them in a dedicated branch rather than in your current working directory.
Common Mistakes to Avoid
While Git stash is easy to use, beginners often make mistakes that can lead to confusion or lost work. Understanding these pitfalls helps you use the feature more effectively.
- Forgetting stashes exist: Stashes are easy to create and easy to forget. Over time, you may accumulate many stashes that you never use again. Regularly review your stash list with
git stash listand clean up unused ones. - Overusing stash instead of commits: Relying too much on stash can indicate that you are not committing often enough. If you find yourself stashing the same work repeatedly, consider whether you should be making smaller, more frequent commits instead.
- Conflicts on apply: Applying a stash to a branch that has diverged significantly can create complex conflicts. If you anticipate this, consider creating a branch from the stash instead.
- Clearing stashes accidentally: The
git stash clearcommand removes all stashes permanently with no confirmation. Use it with extreme caution, especially if you have important work stashed. - Not using stash messages: Without descriptive messages, your stash list becomes a cryptic list of entries that are hard to identify. Always add a message when stashing changes that you might need later.
- Stashing in shared environments: Remember that stashes are local only. They are not pushed to remote repositories. If you need to share temporary work with a colleague, commit to a branch instead.
Avoiding these mistakes improves your efficiency and aligns with guidance in common Git mistakes.
Frequently Asked Questions
- Is git stash permanent?
No. Stashes are temporary and stored only locally. They remain until you explicitly delete them withgit stash droporgit stash clear. If you lose your local repository, all stashes are lost permanently. - Can I share stashes with other developers?
No. Stashes are local to your machine and are never pushed to remote repositories. If you need to share work in progress with a colleague, commit it to a branch and push that branch instead. - What happens if I apply a stash twice?
If you usegit stash apply, the stash remains in the stack and can be applied multiple times. If you usegit stash pop, it is removed after the first application. Usingapplycan be useful if you need to apply the same changes to multiple branches. - Can stash cause conflicts?
Yes. If the files in the target branch have changed since the stash was created, applying the stash may cause merge conflicts. You will need to resolve these conflicts manually, just like with merges. - How many stashes can I create?
There is no strict technical limit, but it is best to keep them organized and remove unused ones regularly. Having dozens of stashes makes it difficult to remember what each one contains, even with descriptive messages. - What is the difference between stash and commit?
A commit creates a permanent, shareable record in your repository that becomes part of your project history. A stash is a temporary, local storage area for changes that are not yet ready to be committed. Use commits for meaningful progress, use stashes for temporary interruptions.
Conclusion
Git stash is a practical and flexible tool that helps you manage temporary changes without affecting your commit history. It allows you to switch tasks quickly, respond to urgent issues, experiment safely, and maintain a clean and professional workflow. By understanding how to use stash effectively, you gain better control over your development process and avoid the frustration of losing work or creating messy commits.
The key to using stash well is knowing when to use it and when to use other Git features. Use stash for short-term interruptions and context switches. Use branches and commits for ongoing work that you plan to share or preserve. When you combine stash with a solid understanding of branching and commits, you have a complete toolkit for managing even the most complex development scenarios.
As you continue learning, combine this knowledge with concepts like Git branching fundamentals and undoing changes in Git to build a strong and efficient workflow. Mastering these tools will significantly improve your productivity and confidence when working with Git, allowing you to handle interruptions gracefully without losing momentum on your important work.
