You are halfway through a change when something more urgent lands: a failing deploy, a review to run, a bug on main. Committing half-work pollutes history; stashing shelves it exactly as it is.
Shelve and return#
git stash # shelve tracked changes, clean working tree
git stash pop # bring the latest stash back and drop it from the list
Two additions cover most real cases. Untracked files are left behind by default, and a new factory or migration is usually untracked:
git stash -u
And a message, because “WIP on main” tells you nothing next week:
git stash push -u -m "invoice pdf: half the template"
The pile#
git stash list
git stash show -p stash@{1}
git stash apply stash@{1}
pop applies and drops; apply applies and keeps. Reach for apply when the same shelved work might go on more than one branch, or whenever you are not sure - a stash you keep costs nothing, a stash you dropped and needed is gone.
Stash part of the mess#
Sometimes half the working tree belongs to the urgent thing and half to your paused work. Pathspecs split them:
git stash push -m "just the config tweak" config/queue.php .env.example
Only those paths are shelved; the rest of the mess stays where it was.
When the stash grew into real work#
A shelved experiment that turned out to be the fix does not belong on top of whatever your working tree has become. Give it its own branch:
git stash branch fix/invoice-pdf stash@{0}
That creates the branch from the commit you stashed on, applies the stash there, and drops it.
The honest warnings#
- Stashes are local. They are never pushed, so they are not a backup and your self-hosted remote never sees them. Anything you would miss should be a commit on a branch.
popcan conflict if the tree moved on. It works like a merge: resolve, and the stash stays in the list if the pop fails.- Stashes fossilize. If
git stash listshows entries from last month, they are todos in disguise - apply them to a branch or drop them.
If the context switch is a review rather than an emergency, a worktree beats a stash entirely: the working tree stays untouched and the PR runs next door. But for the five-minute interruption, stash is the right size of tool.
Share this post
Keep reading
Annotating Commits with git notes: Metadata Without Rewriting History
Some things belong on a commit but not in it: review links, benchmark results, the ticket nobody remembered to reference. git notes adds them after the fact, no rebase required.
Backing Up Your Git Server So It Actually Restores
Every clone is a partial backup - but hooks, config and server state live outside the repo. Mirror, bundle, copy off-site, and rehearse the restore.
Cherry-Picking: One Commit Without the Branch
Cherry-pick copies a single commit onto your branch and leaves the rest behind. Right for hotfixes across release branches, wrong as a sync strategy.