Git Stash

Park unfinished changes with git stash, list, apply and drop stashes, include untracked files and turn a stash into a branch.

Lesson 10 of 30Intermediate17 min read

You're halfway through a new feature when a message arrives: there's an urgent bug on the live site. Your work isn't ready to commit, but you need a clean working folder to switch branches and fix the bug. Committing half-finished code would clutter the history, and copying files somewhere by hand is error-prone.

git stash solves exactly this. It takes your uncommitted changes, puts them on a stack of saved work and returns your working folder to the last commit. You can then switch branches, fix the bug, come back and restore your changes as if nothing had happened.

You met the basic idea in the undoing changes lesson. This lesson goes further: naming stashes, keeping several at once, the difference between pop and apply, including new files, stashing only part of your work and handling conflicts when a stash doesn't apply cleanly.

Stashing and restoring

Terminal
git stash                      # save changes, clean the working folder
git stash push -m "half-done search box"
git stash pop                  # restore the most recent stash and remove it
  • git stash saves your staged and unstaged changes to tracked files.
  • push -m "message" gives the stash a description, which makes a big difference once you have more than one.
  • git stash pop reapplies the newest stash and deletes it from the stack.
  • After stashing, git status reports a clean working tree, so switching branches is safe.

Several stashes, apply and drop

Stashes form a stack: the newest is stash@{0}, the one before it stash@{1}, and so on.

CommandWhat it does
git stash listShow all stashes with their messages
git stash show -p stash@{1}Show the changes inside a stash
git stash apply stash@{1}Reapply a stash but keep it on the stack
git stash pop stash@{1}Reapply a stash and remove it
git stash drop stash@{1}Delete a stash without applying it
git stash clearDelete every stash

Use apply when you might want the same changes on more than one branch, or when you're not sure they'll apply cleanly.

New files and partial stashes

By default, untracked files, ones Git has never seen, stay in your folder. Include them with:

Terminal
git stash -u          # --include-untracked

To stash only some changes, use git stash push with file names, or git stash push -p to choose individual chunks interactively. git stash --keep-index stashes only what isn't staged, which is handy for testing exactly what you're about to commit.

Conflicts and stash branches

If the branch has changed since you stashed, applying the stash can cause a conflict, just like a merge. Resolve the conflict markers, git add the files, and, if you used pop, drop the stash yourself afterwards, because Git keeps it when a pop hits a conflict.

When a stash is too tangled to apply, turn it into its own branch:

Terminal
git stash branch search-box-wip stash@{0}

This creates a new branch starting from the commit where you made the stash, applies the stash there (so there's no conflict), and drops it. You can then commit the work properly and merge it later.

Git Stash Syntax

Stash commands

git stash push -m "message"
git stash -u
git stash list
git stash show -p stash@{0}
git stash pop
git stash apply stash@{1}
git stash drop stash@{1}
git stash branch new-branch stash@{0}

Git Stash Summary

  • git stash saves uncommitted changes and cleans the working folder; add -m for a message.
  • git stash list shows the stack; stash@{0} is the newest.
  • pop applies and removes a stash; apply keeps it; drop and clear delete stashes.
  • -u includes untracked files; push -p stashes chosen parts.
  • Resolve stash conflicts like merges, or use git stash branch to apply a stash on a fresh branch.

Git Stash Examples

Each example shows the code, the output it produces and what each part does.

Example 1

Pausing a feature for an urgent fix

Terminal
git status --short
git stash push -m "search box: input and styles"
git switch main
# ...fix the bug and commit on main...
git switch search-box
git stash pop
git status --short
Output
 M index.html
 M styles.css
Saved working directory and index state On search-box: search box: input and styles
Switched to branch 'main'
Switched to branch 'search-box'
On branch search-box
Changes not staged for commit:
	modified:   index.html
	modified:   styles.css
Dropped refs/stash@{0} (e4c1a9b...)
 M index.html
 M styles.css
Line-by-line explanation
  1. Line 1Two files have uncommitted changes.
  2. Line 2Stash them with a description.
  3. Lines 3 to 4The working folder is clean, so switching to main for the fix is safe.
  4. Line 6pop brings the changes back and removes the stash.
Example 2

Working with several stashes

Terminal
git stash push -m "experiment: new colours"
git stash push -m "experiment: bigger buttons"
git stash list
git stash apply stash@{1}
git stash list
Output
Saved working directory and index state On main: experiment: new colours
Saved working directory and index state On main: experiment: bigger buttons
stash@{0}: On main: experiment: bigger buttons
stash@{1}: On main: experiment: new colours
On branch main
Changes not staged for commit:
	modified:   styles.css
stash@{0}: On main: experiment: bigger buttons
stash@{1}: On main: experiment: new colours
Line-by-line explanation
  1. Line 3The newest stash is always stash@{0}.
  2. Line 4Apply the older "new colours" stash by its name.
  3. Line 5apply keeps the stash in the list, unlike pop.
Example 3

Including a new file

Terminal
git status --short
git stash
git status --short
git stash -u
git status --short
Output
 M app.js
?? notes.md
Saved working directory and index state WIP on main: 9d41e07 Add contact form
?? notes.md
Saved working directory and index state WIP on main: 9d41e07 Add contact form
Line-by-line explanation
  1. Line 1app.js is modified and notes.md is a new, untracked file.
  2. Lines 2 to 3A plain stash saves app.js but leaves notes.md behind.
  3. Lines 4 to 5-u stashes the untracked file too, leaving the folder completely clean. There are now two stashes.

Common Git Stash Mistakes

Forgetting untracked files

Don't
git stash
git switch other-branch    # new files come along and may clash
Do
git stash -u
git switch other-branch

Losing track of anonymous stashes

Don't
git stash
git stash
git stash
git stash list   # three entries all called "WIP on main"
Do
git stash push -m "login form validation"

Running git stash clear by accident

Don't
git stash clear          # every stash is gone
Do
git stash list
git stash drop stash@{2} # remove only the one you don't need

Git Stash in Real Projects

Stash in daily work

Developers stash constantly: before pulling when they have local edits, before switching branches to review a teammate's work, and when an urgent bug interrupts a feature. Editors like VS Code and tools like GitHub Desktop show stashes in their interface, but they run these same commands underneath.

Git Stash FAQ

How do I see what's inside a stash?

git stash show lists the files the latest stash changed, and git stash show -p shows the full diff. For an older stash, add its name: git stash show -p stash@{2}.

How do I recover a stash I dropped by mistake?

The stash's commit still exists for a while, it's just unreferenced. Run git fsck --no-reflog and look for lines starting "dangling commit", check them with git show <hash>, then run git stash apply <hash> on the right one. Do this soon, because Git eventually cleans up unreferenced objects.

Can I apply a stash on a different branch?

Yes. Stashes aren't tied to the branch you made them on, so you can switch branches and run git stash apply or git stash pop there. If the files have changed on that branch, you may get conflicts to resolve, just as with a merge.

Does git stash keep staged and unstaged changes separate?

It saves both, but by default git stash apply and git stash pop restore everything as unstaged changes. Add --index, as in git stash pop --index, to put staged changes back into the staging area as well.

Are stashes pushed to GitHub?

No. Stashes live only in your local repository, and git push doesn't send them. If you need to move unfinished work to another computer, commit it on a branch and push that instead.

Git Stash Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Fill in the blankseasy

Complete the command that saves your changes with a description.

git stash   "half-done header"
Multiple choiceeasy

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

Predict the outputmedium

You run git stash twice. Which stash is stash@{0}?

Multiple choicemedium

Which option includes untracked files in a stash?

Multiple choicehard

What does git stash branch fix-wip stash@{0} do?

Git Stash Quiz

5 questions to check what you learned.

  1. What does git stash do?

    • Deletes your changes
    • Saves uncommitted changes and cleans the working folder
    • Makes a commit
    • Pushes your changes
  2. Are stashes pushed to GitHub with git push?

    • Yes, always
    • Only named stashes
    • Only with -u
    • No, they stay on your computer
  3. Which command shows the changes inside a stash?

    • git stash list
    • git stash show -p
    • git stash diff
    • git log stash
  4. What happens to a stash when git stash pop hits a conflict?

    • It's kept, so you can drop it yourself after resolving the conflict
    • It's deleted anyway
    • It's pushed to a new branch
    • Git refuses to apply it at all
  5. When is committing to a WIP branch better than stashing?

    • Never
    • When the change is tiny
    • When the work must wait for days or should be backed up remotely
    • When you're on main