100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Bash

Stashing Changes

Learn how git stash lets you temporarily shelve uncommitted work so you can switch context cleanly, then reapply it later without polluting your commit history.

Undoing ChangesBeginner8 min readJul 9, 2026
Analogies

Stashing Changes

Every developer hits the same interruption: you're midway through editing a feature when an urgent bug report arrives and you need a clean working directory to switch branches. Committing half-finished work just to switch context pollutes history with noise commits like 'wip' or 'temp'. git stash solves this by taking your uncommitted changes — both staged and unstaged — and saving them onto a stack, restoring your working directory to match HEAD. You can then switch branches, fix the bug, and later pop the stash to continue exactly where you left off. Stashes live locally in .git/refs/stash and are not shared when you push, so they are strictly a personal, temporary bookkeeping tool.

🏏

Cricket analogy: A batsman at 45* gets pulled off for an injury timeout; rather than declaring the innings, the scoreboard 'stashes' his exact score and stance so he can resume at 45* later, recorded only in the dressing room, never broadcast.

Basic stash workflow

The default git stash (equivalent to git stash push) captures tracked, modified files — both staged and unstaged — and reverts them in your working tree. git stash list shows every stash as a stack entry, most recent first, named stash@{0}, stash@{1}, and so on. git stash pop applies the most recent stash and removes it from the stack; git stash apply does the same but leaves the entry in place, which is useful if you want to apply the same stashed changes to multiple branches.

🏏

Cricket analogy: A squad's reserve-bench list stacks players most-recently-benched first; calling up the top name both activates and removes them from the bench, while a loan call-up activates them but keeps them listed as an available reserve too.

bash
# Save uncommitted work before switching branches
$ git status
On branch feature/checkout-flow
Changes not staged for commit:
  modified:   src/checkout/CartSummary.tsx
  modified:   src/checkout/utils.ts

$ git stash push -m "wip: cart summary tax calc"
Saved working directory and index state On feature/checkout-flow: wip: cart summary tax calc

$ git status
On branch feature/checkout-flow
nothing to commit, working tree clean

$ git checkout main
$ git checkout -b hotfix/null-price-crash
# ... fix the urgent bug, commit, push ...

$ git checkout feature/checkout-flow
$ git stash list
stash@{0}: On feature/checkout-flow: wip: cart summary tax calc

$ git stash pop
# working tree changes are restored and the stash entry is dropped

Selective and advanced stashing

Stashing everything isn't always right. git stash push -- <path> stashes only specific files, leaving the rest of your working directory untouched. git stash --keep-index stashes changes but leaves what's already staged intact in the working tree, which is handy when you want to keep a partial commit ready. By default, untracked and ignored files are left alone; pass --include-untracked to sweep up new files as well, or --all to include even ignored files (useful before a clean rebuild). You can also inspect a stash's contents without applying it using git stash show -p stash@{0}, or create a new branch directly from a stash with git stash branch <branch-name>, which is the safest way to resolve a stash that conflicts with the current working tree.

🏏

Cricket analogy: A coach can bench just the injured bowler while keeping the rest of the XI on the field; new unregistered net bowlers can be included too, and the coach can review a benched player's exact fitness report or build an entirely new development squad around them if reintegrating causes selection conflicts.

Think of the stash as a Ctrl+Z-proof clipboard for your entire working directory: it's a mini commit that never appears in git log, sitting in a separate reflog-like stack (git stash list is literally backed by the refs/stash reflog) until you explicitly pop, apply, or drop it.

git stash pop can produce merge conflicts if the branch has diverged since you stashed. If a pop fails partway through, the stash entry is NOT automatically dropped — resolve the conflicts, stage the files, and then manually run git stash drop, or you'll end up with a stale, already-applied stash sitting in your stack.

Stashes also accumulate silently and are easy to forget, especially across multiple feature branches. git stash drop stash@{1} removes a specific entry without applying it; git stash clear wipes the entire stack and is irreversible in the normal sense (though the underlying commits are still recoverable briefly via the reflog and git fsck --unreachable). A good habit is running git stash list at the start of each day — a growing stash stack is usually a sign that work is being shelved instead of properly committed to a branch.

🏏

Cricket analogy: A manager can release one specific reserve from the bench list without touching the rest, or clear the entire bench at once, though released players can briefly be re-signed via the transfer archive; checking the bench list every morning keeps the squad from quietly accumulating unused reserves.

  • git stash push -m "message" saves staged and unstaged changes and restores a clean working tree.
  • Stashes form a LIFO stack (stash@{0} is newest); use git stash list to inspect it.
  • git stash pop applies and removes the entry; git stash apply applies but keeps it for reuse.
  • Use --include-untracked or --all to capture new or ignored files as well.
  • git stash branch <name> is the safest way to apply a stash that would otherwise conflict.
  • Stashes are local-only — they never get pushed to a remote, so don't rely on them for backup.

Practice what you learned

Was this page helpful?

Topics covered

#Bash#GitVersionControlStudyNotes#SoftwareEngineering#StashingChanges#Stashing#Changes#Stash#Workflow#StudyNotes#SkillVeris