Concept and History of Git Stash
Git stash is a feature first introduced in Git version 1.5.3 in 2007. It provides a mechanism to save changes in the Working Directory (modified tracked files and staged changes) to a stack-based temporary storage without committing, allowing restoration later. This feature is useful when you need to urgently switch to another branch while working, or when you need to fetch changes from a remote repository but your current work is not ready for a commit.
When attempting to switch branches with uncommitted changes, Git displays the following error message and refuses the switch. This happens because changes in the current Working Directory might conflict with files in the branch you’re trying to checkout.
error: Your local changes to the following files would be overwritten by checkout:
file.txt
Please commit your changes or stash them before you switch branches.
Aborting
Basic Usage
Saving Changes: git stash
The git stash command saves changes from the Working Directory and Staging Area to the stash stack and reverts the Working Directory to a clean state matching the last commit. By default, it only saves changes to tracked files (files already being tracked by Git) and does not include untracked files or files ignored by .gitignore.
git stash
To save with a message, use the save subcommand (or push -m). This is useful for identifying what each stash represents when managing multiple stashes.
git stash save "Working on login feature"
git stash push -m "Working on login feature" # Recommended since Git 2.13+
Viewing Stash List: git stash list
This command displays a list of saved stashes. Each stash is referenced by an index in the format stash@{n}, with the most recently saved being stash@{0}. The branch name and commit message are also displayed, helping identify under what circumstances each stash was created.
git stash list
# stash@{0}: WIP on main: abc1234 feat: implement login
# stash@{1}: On develop: def5678 fix: bug fix
Applying Stash: git stash apply vs pop
Two commands apply a saved stash back to the Working Directory: apply and pop. apply applies the stash but keeps it in the stack, allowing the same stash to be applied to multiple branches. pop applies and simultaneously removes from the stack, which is the recommended approach for typical use. To apply a specific stash, you can specify its index.
git stash apply # Apply most recent, keep in stack
git stash pop # Apply most recent and remove from stack
git stash apply stash@{2} # Apply specific stash
An important difference is that when using pop, if a conflict occurs, the stash is not automatically removed and remains in the stack, requiring manual drop after resolving the conflict.
Removing Stash: git stash drop and clear
To remove a specific stash from the stack, use drop. To remove all stashes at once, use clear. Without specifying an index, drop removes the most recent stash (stash@{0}).
git stash drop # Remove most recent stash
git stash drop stash@{1} # Remove specific stash
git stash clear # Remove all stashes
Advanced Options
Including Untracked Files: -u option
By default, stash only saves changes to tracked files. To include newly created files that haven’t been git added yet (untracked files), use the -u or --include-untracked option.
git stash -u
Including Ignored Files: -a option
To stash everything including files ignored by .gitignore, use the -a or --all option. This is used in special cases where build artifacts or cache files need to be temporarily saved.
git stash -a
Viewing Stash Contents: git stash show
You can view changes stored in a stash like a commit. Adding the -p option shows detailed changes in diff format, which is useful for checking what’s in a stash before applying it.
git stash show # List of changed files
git stash show -p # Detailed view in diff format
git stash show stash@{1} # View specific stash
Conflict Resolution
Conflicts may occur when applying a stash if the current Working Directory contents differ. When conflicts occur, conflict markers (<<<<<<<, =======, >>>>>>>) appear in files just like merge conflicts. After manually resolving conflicts, stage with git add. If you used pop, the stash remains in the stack and must be removed with git stash drop.
# When conflict occurs
Auto-merging file.txt
CONFLICT (content): Merge conflict in file.txt
# Resolution steps
# 1. Open file and manually resolve conflict markers
# 2. git add file.txt
# 3. git stash drop (when using pop)
Practical Usage Scenarios
Emergency Bug Fix
When an urgent bug fix request comes in while developing a feature, save current work with stash, switch to the bug fix branch, complete the fix, return to the original branch, and restore the stash.
git stash push -m "Working on feature/login"
git checkout hotfix/critical-bug
# Bug fix work and commit
git checkout feature/login
git stash pop
Fetching Remote Changes
When you need to fetch the latest changes from a remote repository while having uncommitted local changes, save local changes with stash, perform pull, then reapply. If conflicts occur, resolve them before proceeding.
git stash
git pull origin main
git stash pop # Resolve conflicts if any, then git stash drop
Conclusion
Since its introduction in Git 1.5.3 in 2007, Git stash has become an essential feature for temporarily saving uncommitted changes and restoring them later. Understanding the difference between apply and pop (whether to remove from stack), including untracked files with the -u option, and knowing that manual drop is required after conflict resolution enables flexible management of workflows in various situations such as branch switching, urgent tasks, and remote synchronization.