You are deep in coding a new feature. Files are modified, some are staged, ideas are flowing. Then your phone buzzes: production is down, and you are the only one who can fix it. You need to switch to the main branch immediately, but you cannot commitWhat is commit?A permanent snapshot of your staged changes saved in Git's history, identified by a unique hash and accompanied by a message describing what changed. your half-finished work. What do you do?
This is where git stash saves the day. It is like a clipboard for your entire working directory. You cut your changes, do something else, and paste them back when you return. No commits needed. No lost work.
git commit -m "WIP" followed by a reset later. That works but clutters your history. Stash is the purpose-built tool for this exact situation and keeps your commit log clean.Why stash beats "WIP" commits
| Approach | History impact | Recovery complexity | Risk |
|---|---|---|---|
git stash | None, history stays clean | git stash pop | Low |
git commit -m "WIP" | Pollutes log, needs reset later | git reset --soft HEAD~1 | Medium, might forget |
| Leave files uncommitted | Cannot switch branches | N/A | High, Git blocks you |
Stash is the right tool when you need to temporarily shelve work without creating a commitWhat is commit?A permanent snapshot of your staged changes saved in Git's history, identified by a unique hash and accompanied by a message describing what changed..
Basic stash operations
Creating a stash
# Stash all uncommitted changes
git stash
# Stash with a descriptive message (always do this)
git stash push -m "WIP: user authentication with JWT"After stashing, your working directory is clean. Run git status and you will see nothing to commitWhat is commit?A permanent snapshot of your staged changes saved in Git's history, identified by a unique hash and accompanied by a message describing what changed.. Your changes are safely stored on the stash stack.
Viewing your stashes
git stash listOutput:
stash@{0}: On feature-login: WIP: authentication form validation
stash@{1}: On main: temp fix for header bug
stash@{2}: On feature-api: API integration in progressThe stack works like a stack of plates. stash@{0} is the most recent (top). Higher numbers are older.
Retrieving a stash
Pop (retrieve and remove from stack):
git stash popApply (retrieve but keep in stack):
git stash apply
# Apply a specific stash
git stash apply stash@{2}Use pop by default. Only use apply if you need to apply the same stash to multiple branches.
Removing stashes
# Drop the most recent stash
git stash drop
# Drop a specific stash
git stash drop stash@{1}
# Clear all stashes (irreversible)
git stash clearA complete stash workflow
The most common real-world scenario: an urgent bug interrupts your feature work.
# You are working on a feature with uncommitted changes
git status
# modified: login.js
# modified: auth.css
# Stash your work with a descriptive message
git stash push -m "WIP: auth form validation"
# Switch to main and create a hotfix branch
git checkout main
git checkout -b hotfix/critical-bug
# Fix the bug
git add src/header.js
git commit -m "fix: correct null pointer in header navigation"
git push -u origin hotfix/critical-bug
# Return to your feature branch
git checkout feature-login
# Retrieve your stashed work
git stash pop
# Continue where you left off
git status
# modified: login.js
# modified: auth.cssThe entire context switch takes 30 seconds. No lost work, no messy commits.
Advanced stash options
# Stash only staged files
git stash --staged
# Stash unstaged files but keep staged ones
git stash --keep-index
# Stash specific files only
git stash push -m "WIP: API layer" api.js utils.js
# Include untracked (new) files
git stash -u
# Create a new branch from a stash
git stash branch new-feature-branch stash@{0}| Option | Use case |
|---|---|
--staged | Stash what you staged, keep unstaged changes |
--keep-index | Test staged changes in isolation |
push file1 file2 | Stash only specific files |
-u | Include new files Git does not track yet |
stash branch name | Turn a stash into its own feature branch |
Quick reference
| Command | What it does |
|---|---|
git stash | Stash all changes |
git stash push -m "msg" | Stash with a descriptive message |
git stash list | Show all stashes |
git stash pop | Apply and remove the most recent stash |
git stash apply | Apply but keep the stash |
git stash apply stash@{n} | Apply a specific stash |
git stash drop | Delete the most recent stash |
git stash clear | Delete all stashes |
git stash -u | Include untracked files |
git stash branch name | Create a branch from a stash |