Skip to content
Home
Git Stash: Save and Restore Work in Progress

Git Stash: Save and Restore Work in Progress

Git Git 8 min read 1499 words Beginner ExcellentWiki Editorial Team

Git stash temporarily shelves your uncommitted changes so you can work on something else. It is one of Git’s most practical features for everyday development — every developer encounters situations where they need to pause mid-task and switch context without losing progress.

The Basic Workflow

The most common stash scenario: you are deep into a feature branch when an urgent bug is reported on main.

# You're working on a feature, but need to fix a bug urgently
git stash                    # save your work
git checkout main
# fix the bug, commit, push
git checkout feature
git stash pop                # restore your work

The git stash command saves your working directory changes and index (staged changes) to a stack of unfinished work, then reverts your working directory to match the HEAD commit. Your working directory is clean, and you can safely switch branches. When you return, git stash pop applies the most recent stash and removes it from the stack.

Stash Commands

Git’s stash system supports a full suite of commands for managing saved work:

git stash                    # stash tracked files
git stash push -m "WIP: refactoring auth"  # named stash
git stash -u                 # stash + untracked files
git stash -a                 # stash everything (including ignored)

git stash list               # show all stashes
git stash show               # show summary of latest stash
git stash show -p            # show full diff of latest stash

git stash pop                # apply + remove latest stash
git stash apply              # apply without removing
git stash apply stash@{2}    # apply a specific stash

git stash drop               # remove latest stash
git stash drop stash@{1}     # remove specific stash
git stash clear              # remove ALL stashes

The difference between pop and apply is subtle but important. pop applies the stash and removes it from the stack. apply applies the stash but keeps it on the stack — useful when you want to apply the same stash to multiple branches or want to verify it applies cleanly before committing to it.

Named Stashes

When you have multiple stashes saved, remembering what each one contains becomes difficult. Named stashes solve this problem:

git stash push -m "refactor user model"
git stash push -m "fix login bug"
git stash push -m "add tests for api"

git stash list
stash@{0}: On main: add tests for api
stash@{1}: On main: fix login bug
stash@{2}: On main: refactor user model

git stash apply stash@{1}    # apply the "fix login bug" stash

Without meaningful messages, git stash list shows only branch names and commit hashes. Always add a -m message — your future self will thank you when you have a dozen stashes accumulated over a week. A common convention is to include the branch name and a brief description: git stash push -m "feature/payments: WIP on validation logic".

Working with Untracked Files

By default, git stash only stashes tracked files:

# Stash including new (untracked) files
git stash -u

# Stash including everything
git stash --all

The -u flag (short for --include-untracked) stashes new files that Git has never seen before. The --all flag goes further and also includes ignored files (those listed in .gitignore). Use -u for most cases — stashing ignored files is rarely useful and can clutter your stash with build artifacts.

Partial Stash

Sometimes you only want to stash a subset of your changes. Git supports both file-level and hunk-level partial stashing.

git stash push -m "only config changes" -- src/config.js

Or interactively:

git stash -p
# Git prompts you for each hunk — choose which to stash

Interactive stashing is useful when you have mixed changes in the same file — some bug fixes you want to commit now and some refactoring you want to save for later. Git presents each changed hunk and lets you decide whether to stash it. You answer y (stash this hunk), n (don’t stash), q (quit), or a (stash all remaining hunks).

Create a Branch from a Stash

One of the most useful stash features is recovering a stash onto a new branch. This is a lifesaver when you accidentally stashed on the wrong branch.

git stash branch new-feature stash@{0}

This creates a new branch at the commit where the stash was made, applies the stash, and drops it. This bypasses any conflicts that might arise from applying the stash to a different commit context.

Recovering Dropped Stashes

If you accidentally drop a stash, it is not immediately lost — Git keeps unreachable objects for a grace period:

git stash drop stash@{1}  # oops

# Check git reflog for the stash commit hash
git fsck --unreachable | grep commit | cut -d' ' -f3 | xargs git log --oneline

# Apply the commit found
git cherry-pick <commit-hash>

This technique searches for unreachable commits in Git’s object database. It is not guaranteed to work (Git may garbage-collect unreachable objects), but it is worth trying before abandoning hope.

Common Workflows

Interrupted Work

# Context: Working on feature-branch when urgent bug appears
git add -A
git stash save -u "feature X in progress"
git checkout main
git checkout -b hotfix/urgent-bug
# ... fix bug, commit, push ...
git checkout feature-branch
git stash pop

Testing Different Approaches

# Try approach A
git stash push -m "approach A"
# Try approach B
git stash push -m "approach B"
# Try approach C

# Compare approaches by applying in temp branches
git stash branch test-a stash@{2}
git stash branch test-b stash@{1}

This is a powerful technique for exploring multiple solutions. Each approach lives in its own stash. When you find the best one, you can compare them side-by-side in temporary branches without polluting your working tree.

Stash Before Pull

A common but often overlooked use case is stashing before pulling to avoid merge conflicts:

git stash push -m "auto-save before pull"
git pull --rebase
git stash pop

If the pull creates conflicts, this pattern lets you resolve them without worrying about losing your uncommitted work.

Stash Conflicts and How to Handle Them

When you apply a stash to a branch that has diverged significantly from where the stash was created, conflicts can occur. Git treats stash application like a merge:

git stash pop
# Auto-merging src/config.js
# CONFLICT (content): Merge conflict in src/config.js

To resolve, edit the conflicted files, stage them, and continue. If the conflicts are too complex, you can drop the stash without applying:

# Abandon the conflicted stash
git reset --hard HEAD
git stash drop

Better yet, use git stash branch to create a new branch at the original stash point, apply the stash there, and then merge or rebase manually.

Stash in CI/CD Scripts

Stash is not just for interactive use. It is also valuable in automation scripts where you need to temporarily save state:

#!/bin/bash
# CI script that runs tests, stashes changes, tests again
git stash push -m "ci: auto-stash before checkout"
git checkout main
npm run test:integration
RESULT=$?
git stash pop
exit $RESULT

This pattern is useful when a CI job needs to test multiple branches in sequence without losing the original working state.

Stash vs Commit

SituationStashCommit
Quick context switch
Work in progress, not ready
Saving progress long-term
Sharing with others
Testing multiple approaches
Need a clean working directory

The general rule: use stash for temporary, short-term storage (hours to a day). If you need to save work for longer, create a commit on a temporary branch. Commits are tracked in the reflog, can be pushed to a remote, and are visible to your CI system — all things that make them better for longer-term work preservation.


Related: Learn how to undo commits and open pull requests.

FAQ

Q: Does git stash stash staged and unstaged changes? A: By default, yes. Both staged and unstaged changes to tracked files are stashed. Untracked files require -u or --include-untracked.

Q: What is the difference between git stash pop and git stash apply? A: pop applies the stash and removes it from the stack. apply applies the stash but keeps it in the stash list for later reuse.

Q: Can I recover a stash after git stash clear? A: It is difficult but not impossible. git stash clear removes all stash references. You can try git fsck --unreachable to find orphaned stash commits, but there is no guarantee they will still exist.

Q: How many stashes can I have? A: There is no hard limit, but practical experience suggests keeping stashes to a single-digit number. Old stashes become stale and difficult to apply without conflicts.

Q: Does stash work across branches? A: Yes. Stashes are global to the repository, not tied to a specific branch. You can stash on one branch and apply on another.

Q: What happens if a stash fails to apply cleanly? A: Git reports merge conflicts. Resolve them the same way you would resolve any merge conflict — edit the conflicted files, stage them, and continue working. The stash branch command can help if conflicts are persistent.

Section: Git 1499 words 8 min read Beginner 756 articles in section Report inaccuracy Back to top