open atlas
↑ Back to track
Git, from zero to senior GIT · 07 · 01

Stashing work in progress

git stash shelves uncommitted tracked changes and gives you a clean tree, so you can switch branches mid-work. pop reapplies and drops the entry; apply reapplies but keeps it. Stashes form a stack you list and drop — but they are local-only and easy to forget.

GIT Middle ◷ 15 min
Level
FoundationsJuniorMiddleSenior

You are halfway through a feature, files everywhere, nothing ready to commit — and a production bug lands that you must fix on main right now. Git refuses to switch branches because the checkout would clobber your edits. You do not want to commit half-broken code just to move. There is a parking lot for exactly this: git stash.

By the end of this lesson you will be able to shelve dirty changes to get a clean tree, switch contexts, and bring the work back — knowing exactly when pop and apply differ and where the stash actually lives.

Goal

After this lesson you can use git stash to set work in progress aside and restore it, explain the stash stack and the difference between pop and apply, and avoid the classic traps around untracked files and forgotten stashes.

1

git stash records your uncommitted tracked changes and resets the working tree to HEAD. It takes everything modified-and-tracked — both staged and unstaged — saves it as a hidden commit-like object, and rolls your files back to a clean state matching the last commit:

git stash            # shorthand for: git stash push
git status           # now clean — your edits are parked, not lost

The key idea: you get a clean tree without committing and without throwing work away. Now git switch main succeeds.

2

Stashes form a stack, and you can list it. Each git stash pushes a new entry on top, numbered from the most recent:

git stash list
# stash@{0}: WIP on feature: 9f3c1a2 Add filter UI
# stash@{1}: WIP on feature: 9f3c1a2 Add filter UI

stash@{0} is the newest. Because the auto-generated messages all look alike, name your stashes so future-you can tell them apart:

git stash push -m "half-done filter validation"
3

pop reapplies and removes; apply reapplies and keeps. To get your work back:

git stash pop            # reapply stash@{0}, then delete it from the stack
git stash apply          # reapply stash@{0}, but LEAVE it on the stack
git stash apply stash@{1}  # reapply a specific older entry

Use pop for the normal “resume where I left off” case. Use apply when you want the same change on several branches, or when you are nervous about conflicts and want a safety copy until you confirm it landed cleanly.

Edge cases

By default git stash ignores untracked files (new files git has never seen) and ignored files. So a brand-new config.local.js stays sitting in your working tree even after you stash — and may block the branch switch you were trying to do. Add -u (--include-untracked) to sweep new files in too, or -a (--all) to also include ignored files. Forgetting this is the most common “but I stashed everything!” surprise.

4

pop can fail with a conflict — and then it does not drop the stash. If the branch moved on and the stashed change overlaps, reapplying produces merge conflicts. Resolve them like any merge, then git add the files. Note that a conflicting pop keeps the stash entry (so you do not lose it mid-conflict); drop it yourself once resolved. Two more tools worth knowing:

git stash drop stash@{1}   # delete one entry without applying it
git stash branch fix-wip   # create a branch FROM the stash and apply it there

git stash branch is the clean escape hatch when the stash no longer applies to the current branch: it checks out the commit the stash was made on, so the change applies without conflict.

Worked example

The emergency hotfix, end to end.

You are on feature/search with a dozen modified files and one new file search.test.js that git has never tracked. A pager alert says checkout is broken on main.

git stash push -u -m "search WIP + new test"   # -u so the new test file goes too
git switch main
# ... fix the production bug, commit, push ...
git switch feature/search
git stash pop

After pop, all twelve edits and the new test file are back exactly as you left them, and the stash stack is empty again. If pop had reported a conflict (say main’s hotfix also touched a file you had open), you would resolve it, git add the result, then git stash drop to clear the entry that the conflicting pop left behind.

Common mistake

A stash is local-only and invisible to everyone else. It is not part of any commit, never gets pushed, and does not show up in git log. People routinely stash something “for a minute,” start new work, and forget it for weeks — then a git stash list reveals a pile of half-finished entries. Treat the stash as a short-lived parking lot, not storage: if work matters for more than an afternoon, make a commit on a branch instead.

Check yourself
Quiz

You want to apply a stashed change onto two different branches in turn. Which command should you use, and why?

Recap

git stash shelves your uncommitted tracked changes and hands you a clean working tree, so you can switch branches or pull without committing half-done work. Stashes pile onto a stack (stash@{0} newest) that you can list, name with -m, and drop. pop reapplies and removes the entry; apply reapplies but keeps it for reuse. Remember -u to include untracked files, that a conflicting pop leaves the entry in place, and that stashes are local-only and easy to forget. Next you will copy a single commit from one branch onto another with git cherry-pick.

Practice

Start at the top. Tasks go easiest → hardest: recall a fact, apply it to a case, then a senior-level stretch. Open one, attempt it, then reveal.

recallapplystretch0 of 4 done

Something unclear?

Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.

shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.