git stash & git clean
Quick Summary
git stash saves your uncommitted work to a temporary shelf so you can switch contexts (branches, hotfixes) without losing progress. git clean removes untracked files from your working directory. Together, they keep your workspace clean and flexible.
git stash — Save Work Temporarily
The Problem
You're mid-feature and your boss says "hotfix needed on main NOW." You can't commit half-done work, and you can't switch branches with uncommitted changes.
Solution: Stash it.
sequenceDiagram
participant WD as Working Directory
participant ST as Stash Stack
participant BR as Branches
Note over WD: Working on feature...
WD->>ST: git stash
Note over WD: Workspace is clean!
WD->>BR: git checkout main
Note over BR: Fix the hotfix
BR->>BR: git commit -m "hotfix"
BR->>WD: git checkout feature
ST->>WD: git stash pop
Note over WD: Back to where you left off!
Core Commands
# Save current changes to stash
git stash
# Save with a descriptive message
git stash push -m "WIP: user profile page"
# List all stashes
git stash list
# Restore the most recent stash (and remove it from stack)
git stash pop
# Restore a stash (keep it in the stack)
git stash apply
# Restore a specific stash
git stash apply stash@{2}
# Drop a specific stash
git stash drop stash@{0}
# Clear ALL stashes
git stash clear
Examples
# Save everything (tracked modified + staged)
git stash
Saved working directory and index state WIP on main: a1b2c3d feat: add auth
# List stashes
git stash list
stash@{0}: WIP on main: a1b2c3d feat: add auth
stash@{1}: On feature: WIP user profile page
stash@{2}: On main: debugging session
# Restore and remove from stack
git stash pop
On branch main
Changes not staged for commit:
modified: src/app.js
Dropped refs/stash@{0} (a1b2c3d4e5f6...)
Advanced Stash Options
# Stash including untracked files
git stash -u
# Stash including ignored files too
git stash -a
# Stash only specific files (Git 2.13+)
git stash push -m "only auth changes" src/auth.js src/login.js
# Create a branch from a stash
git stash branch new-feature stash@{0}
# Show what's in a stash (without applying it)
git stash show stash@{0}
git stash show -p stash@{0} # Full diff
Stash conflicts
If the code has changed since you stashed, git stash pop may cause merge conflicts. Resolve them the same way you'd resolve any merge conflict.
git clean — Remove Untracked Files
Removes files that Git doesn't track — build artifacts, temp files, editor debris.
Syntax
git clean -n # Dry run — show what WOULD be deleted
git clean -f # Force delete untracked files
git clean -fd # Delete untracked files AND directories
git clean -fX # Delete only ignored files
git clean -fx # Delete ALL untracked (including ignored)
git clean -i # Interactive mode
Always dry-run first
git clean -f is irreversible. Always run with -n first to preview what will be deleted.
Examples
# Preview what would be removed
git clean -n
Would remove build/
Would remove temp.log
Would remove .env.local
# Actually remove (after reviewing)
git clean -fd
Removing build/
Removing temp.log
# Interactive mode — choose which files to delete
git clean -i
Would remove the following items:
1 - build/
2 - temp.log
3 - .env.local
*** Commands ***
1: clean 2: filter by pattern 3: select by numbers 4: ask each 5: quit
What now> 4
Remove build/ [y/N]? y
Remove temp.log [y/N]? y
Remove .env.local [y/N]? n
Decision Guide
| Scenario | Command |
|---|---|
| Need to switch branches but have uncommitted work | git stash |
| Save stash with a note | git stash push -m "description" |
| Restore saved work | git stash pop |
| Remove build artifacts | git clean -fd (after -n preview) |
Remove only .gitignore-d files | git clean -fX |
| Nuclear cleanup (everything untracked) | git clean -fdx |
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| Stash pop has conflicts | Code changed since stashing | Resolve conflicts manually, then git add |
| Can't find stashed work | Applied with apply (not pop), or cleared | Check git stash list; use git reflog if cleared |
git clean deleted important files | Didn't use -n first | Recover from backup or git reflog (if ever tracked) |
| Stash won't apply to different branch | Significant code divergence | Use git stash branch to create a new branch from the stash |
Best Practices
- Always name your stashes (
-m "description") — unnamed stashes pile up and become confusing - Don't let stashes accumulate — apply or drop them promptly
- Always dry-run
git clean— run with-nbefore-f - Use
git stash -ufor new files — by default, stash ignores untracked files - Prefer committing WIP on a feature branch over stashing, if possible
What's Next
- Branching Fundamentals — Work in parallel with branches
- Conflict Resolution — Handle merge conflicts confidently