Suggest an editImprove this articleRefine the answer for “What is git stash and when to use it?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**git stash** saves both staged and unstaged changes to a stack and cleans your working tree, so you can switch branches or pull without losing work. Run `git stash pop` to reapply. Add `-u` to include untracked files. **Key point:** `pop` applies and drops; `apply` applies and keeps the entry.Shown above the full answer for quick recall.Answer (EN)Image**git stash** temporarily saves your uncommitted working directory and staged changes to a stack, clears your working tree to match the current commit, and lets you reapply them later. ## Theory ### TL;DR - Think of it like folding half-written sticky notes into a drawer: work pauses exactly where it is, desk clears for the urgent task, notes unfold back unchanged - Saves both staged and unstaged changes in one command; add `-u` to capture untracked files too - Core loop: stash, switch branch or pull, pop - `pop` applies the stash and drops it from the stack; `apply` keeps it there - Use stash when uncommitted work blocks you; skip it when changes are stable enough to commit ### Quick example ```bash # On feature branch with uncommitted changes git stash push -m "WIP: login validation" # Output: Saved working directory and index state WIP: login validation git status # On branch feature, nothing to commit, working tree clean git stash pop # Restores everything exactly as it was # Output: Dropped refs/stash@{0} ``` That is the whole pattern. Stash cleans your tree, you do what needs doing, pop brings everything back. ### When to use Stash fits a few specific situations well: - Mid-feature and an urgent bugfix lands: stash on the feature branch, checkout main, fix and commit, come back, pop - Uncommitted changes block `git pull`: stash, pull, pop (handle conflicts after if they come up) - Context switch is too fast for a proper commit: use a descriptive stash message instead of a half-baked commit with "WIP" in the title Skip stash if you expect the reapplication to conflict with incoming changes - create a branch instead. Also skip it if changes are already stable; just commit. ### How git stash works internally Git creates two commits under the hood. The first captures your index (staged files) as a tree. The second captures your working directory diff on top of that. Both get stored in `.git/refs/stash` as a reflog stack, where `stash@{0}` is always the newest entry. `git stash push` calls `git commit-tree` with plumbing commands to bundle these states, then resets HEAD, index, and working tree to the base commit. `git stash pop` replays the diff and removes the reflog entry if there are no conflicts. This is why stash conflicts happen: the stored diff was created relative to one base commit, but by the time you pop, the base may have moved. ### Common mistakes **Forgetting `-u` when you have untracked files:** ```bash npm install new-dep # Creates untracked files git stash # Ignores them by default git checkout other # Those files stay behind or cause confusion ``` Fix: `git stash -u`. Or make sure `.gitignore` properly covers what you do not need tracked. Stash then `git pull --rebase` without popping first: ```bash git stash git pull --rebase origin main # Rewrites base commit history git stash pop # Stash was made against the old base, conflicts likely ``` The stash holds a diff relative to the original base commit. After rebase that base moved. Pop before rebase, or rebase first and pop after. **Assuming `pop` always cleans up on conflict:** ```bash git stash pop # CONFLICT (content): Merge conflict in file.js # Applying stash failed, stash remains ``` When pop hits a conflict, it applies changes with conflict markers but does NOT drop the stash. The safer path: `git stash apply`, resolve manually, then `git stash drop`. Dropping the wrong stash by index: ```bash git stash list # stash@{0}: WIP: new feature # stash@{1}: WIP: older experiment git stash drop stash@{1} # Indices shift on every push or pop ``` Always run `git stash list` right before dropping. With many entries, `git stash branch new-branch stash@{0}` is safer than juggling indices. ### Real-world usage - React contributors stash WIP hooks before `git pull upstream` to keep merges clean (see the CONTRIBUTING.md workflow) - Node.js contributors stash uncommitted benchmarks mid-pull when CI fixes land - VS Code extension developers stash partial TypeScript changes between branch switches - `git stash` vs `git worktree`: stash for quick context switches; worktree when you need two branches open in parallel for a longer stretch ### Follow-up questions **Q:** What is the difference between `git stash apply` and `git stash pop`? **A:** `apply` reapplies the stash but keeps it on the stack. `pop` applies and drops it. Use `apply` when you are not sure the reapplication will go cleanly, so you have a fallback. **Q:** How does git stash handle untracked files? **A:** By default it ignores them. Pass `-u` or `--include-untracked` to stash untracked files. Pass `-a` or `--all` to also include files matched by `.gitignore`. **Q:** What happens if `git stash pop` has a conflict? **A:** Git leaves conflict markers in the affected files and the stash stays on the stack. Pop only drops the entry on a clean apply. Resolve the conflicts, stage the files, then `git stash drop`. **Q:** Can you stash during a rebase or merge conflict? **A:** During an active merge conflict `git stash` will fail. Use `git stash branch new-branch stash@{0}` to create a branch from the stash state instead of applying it directly. **Q:** How is the stash stored internally? Walk through the commit graph. **A:** Two commits: one for the index state (`i`), one for the working directory diff on top (`w`). Both point to HEAD at stash time. The reflog at `.git/logs/refs/stash` tracks the stack. `stash@{0}` is the `w` commit, its parent is `i`, and `i` points back to the original HEAD. **Q:** What is the safest workflow when `git stash pop` keeps conflicting? **A:** Run `git stash branch new-branch stash@{0}`. It creates a branch at the exact commit where the stash was made, applies the stash there (no base mismatch), and drops it if clean. Then merge or rebase that branch the normal way. ## Examples ### Switching branches mid-feature You are editing `Login.jsx` and have utility changes staged when a production issue comes in. ```bash # Staged utils, unstaged Login.jsx changes git stash push -u -m "WIP: login form validation" # -u captures any untracked config files too git checkout main git checkout -b hotfix/auth-token git commit -m "Fix: expired token not clearing session" git push origin hotfix/auth-token git checkout feature/user-auth git stash pop # Login.jsx and utils restored exactly as left ``` If a conflict appears after pop, Git marks the file with `<<<<<<<` markers. Resolve them, stage, then run `git stash drop` to clear the entry. ### Stash conflict after upstream changes This one trips up experienced developers. Staged file A, unstaged file B, untracked file C. Someone pushes a change to B while your stash sits there. ```bash echo "A" > A.txt && git add A.txt echo "B" > B.txt echo "C" > C.txt # untracked git stash push -u -m "partial work" # Meanwhile on remote: B.txt gets a new commit git pull git stash pop # CONFLICT (content): Merge conflict in B.txt # Applying stash failed, stash remains # Do NOT run git stash drop yet # Resolve B.txt manually, then: git add B.txt git stash drop # Now safe to remove ``` A.txt and C.txt restored cleanly. Only B.txt conflicted because both the remote commit and the stash touched the same file. I have seen developers panic at "stash remains" thinking they lost work. Nothing is lost; Git just needs the conflict resolved before it can clean up. ### Stash and rebase: the right order ```bash # Wrong order git stash git pull --rebase origin main # Base moves without your changes git stash pop # Stash diff now points to old base, conflicts very likely # Right order git stash git fetch origin git rebase origin/main # Rebase first on fetched state git stash pop # Pop onto the new base cleanly ``` The stash stores a diff relative to the base commit at the moment you stashed. Rebase changes that base. Keep the order right and you avoid most stash-related headaches.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.