BEGINNERGITSTASH & WORKTREE

Useful git stash Patterns Beyond stash and pop

Stash with a message, stash untracked files, list stashes, apply a specific stash, and stash a single file. The full git stash workflow.

Published May 22, 2026
gitstashworkflowshellproductivity

git stash is more than just stash and pop. With messages, indexes, and selective patterns, it becomes a real branch-juggling workflow tool. This snippet covers the patterns I actually use day to day, not just the basics.

Tested on git 2.43+.

When to Use This

  • Switching branches with uncommitted changes you don't want to commit yet
  • Pulling latest with dirty working tree (stash, pull, pop)
  • Saving experimental changes before trying a different approach
  • Carrying changes between branches without committing

Don't use this when the changes are substantial — commit to a temporary branch instead. Stash is for short-lived "I need to switch branches for a minute" workflows.

Code

# Basic stash and restore
git stash
git stash pop
 
# Stash with a descriptive message
git stash push -m "WIP: refactoring user service"
 
# Stash including untracked files (forgetting -u is the #1 stash mistake)
git stash push -u -m "WIP: new login form scaffolding"
 
# Stash everything including ignored files
git stash push -a -m "Full snapshot before destructive operation"
 
# List all stashes with messages
git stash list
 
# Show what's in a specific stash
git stash show stash@{2}
git stash show -p stash@{2}    # full diff
 
# Apply a specific stash without removing it
git stash apply stash@{2}
 
# Pop a specific stash
git stash pop stash@{1}
 
# Drop a stash you don't need
git stash drop stash@{0}
 
# Drop all stashes
git stash clear

stash@{0} is the most recent stash; stash@{N} is the Nth one back. git stash list shows them in order.

Usage

The "I need to pull but I'm dirty" workflow:

# 1) Stash everything including new files
git stash push -u -m "WIP: dashboard layout"
 
# 2) Pull latest
git pull --rebase origin main
 
# 3) Restore your work
git stash pop

Carrying a change to another branch:

# 1) On feature/login, you accidentally edited a file that belongs in feature/header
git stash push -m "header fix that belongs elsewhere"
 
# 2) Switch branches
git checkout feature/header
 
# 3) Apply (not pop — keep the stash as backup)
git stash apply
 
# 4) When you're sure it landed cleanly, drop the stash
git stash drop stash@{0}

Stashing only specific files:

# Stash only the file(s) you specify
git stash push -m "just the auth changes" -- src/auth.ts src/auth.test.ts

Pitfalls

  • git stash does NOT include untracked files by default. This bites everyone at least once. Use -u to include them. New files you forgot to git add are gone otherwise.
  • pop can have merge conflicts. If the working tree has changed since you stashed, pop may not apply cleanly. The stash isn't dropped automatically when there are conflicts — fix them, then git stash drop.
  • Stashes are local-only. They live in .git/refs/stash. They never get pushed to a remote. Don't rely on them as backup.
  • Stashes accumulate. Run git stash list periodically and clean up. After 30 days you won't remember what WIP: refactoring even meant.
  • git stash show -p is your friend for inspecting a stash before applying it. Don't apply blind.
  • A pop with conflicts marks files as conflicted. Resolve them, git add, and the stash is still there until you git stash drop it manually.

Frequently Asked Questions

What's the difference between git stash pop and git stash apply?

pop applies the most recent stash and removes it from the stash list. apply only applies it without removing — useful when you want to apply the same stash to multiple branches. If apply has merge conflicts, the stash stays around so you can retry.

Does git stash include untracked files?

By default no — only tracked files. Use git stash -u (or --include-untracked) to also stash new files. Use -a (or --all) to also stash files that are git-ignored. Forgetting -u is the #1 reason people 'lose' new files when stashing.

X (Twitter)LinkedIn