Skip to main content
Stashing allows you to save your current work-in-progress changes and switch to a clean working directory. It’s perfect for when you need to quickly switch contexts without committing half-done work.

What is Stashing?

A stash is a temporary storage area for uncommitted changes. It saves both staged and unstaged modifications, then reverts your working directory to match the HEAD commit.

Basic Stashing

Save Your Changes

# Stash current changes
git stash

# Equivalent to:
git stash push

Restore Your Changes

# Apply most recent stash and remove it from stash list
git stash pop

# Apply most recent stash but keep it in stash list
git stash apply

View Stashed Changes

# List all stashes
git stash list

# Output:
# stash@{0}: WIP on main: 5678abc Update docs
# stash@{1}: WIP on feature: 1234def Add feature

# Show changes in most recent stash
git stash show

# Show detailed diff
git stash show -p

Stash Options

Stash with a Message

Provide a descriptive message:
git stash push -m "Work in progress on authentication"

Include Untracked Files

By default, stash ignores untracked files:
# Include untracked files
git stash -u

# or
git stash --include-untracked

Include All Files (Even Ignored)

git stash -a

# or
git stash --all

Stash Only Staged Changes

Stash what’s in the index:
git stash --staged

Keep Index Intact

Stash working directory changes but leave staged changes:
git stash --keep-index
Useful for testing staged changes before committing.

Partial Stashing

Interactively choose what to stash:
git stash -p

# or
git stash --patch
Git will ask for each hunk whether to stash it.

Managing Stashes

Applying Specific Stashes

# Apply a specific stash
git stash apply stash@{2}

# Pop a specific stash
git stash pop stash@{1}

Deleting Stashes

# Drop a specific stash
git stash drop stash@{1}

# Clear all stashes
git stash clear
git stash clear permanently deletes all stashes. They cannot be recovered through normal means.

Creating a Branch from a Stash

Apply stash to a new branch:
git stash branch new-branch-name stash@{1}
This:
  1. Creates a new branch from the commit where the stash was created
  2. Applies the stash to the new branch
  3. Drops the stash if successful

Common Workflows

Interrupted Work

1
You’re working on a feature when urgent work comes up
2
# Stash your current work
git stash -u -m "Feature X in progress"
3
Switch to the urgent task
4
git checkout main
# Fix the urgent issue
git commit -am "Fix critical bug"
5
Return to your feature
6
git checkout feature-branch
git stash pop

Pulling with Uncommitted Changes

# Working directory is dirty
git pull
# Error: Your local changes would be overwritten

# Solution:
git stash
git pull
git stash pop

Testing Partial Changes

# You have both completed and incomplete changes
git add <completed-files>
git stash --keep-index    # Stash incomplete work

# Run tests on completed changes
make test

# If tests pass, commit
git commit -m "Completed feature"

# Restore incomplete work
git stash pop

Saving Unrelated Changes

# While working, you notice and fix an unrelated issue
git add <unrelated-fix>
git stash push --staged -m "Unrelated bug fix"

# Continue with original work
# ...

# Later, apply the unrelated fix on a different branch
git checkout fix-branch
git stash pop

Advanced Usage

Stashing Specific Files

# Stash only specific files
git stash push -m "Stash config files" -- config/*.yaml

# Stash everything except certain files
git stash push -- '*.js' ':!tests/*'

Viewing Stash Contents

# Show files changed in stash
git stash show stash@{0}

# Show full diff
git stash show -p stash@{0}

# Show only untracked files in stash
git stash show --only-untracked stash@{0}

Creating a Stash Without Removing Changes

# Create stash but don't clean working directory
git stash create

# This outputs a commit hash, which you can apply later:
git stash store -m "Message" <commit-hash>

Stash Structure

A stash is represented as a commit with a special structure:
      .----W    (working directory changes)
     /    /
----H----I      (index changes)
  • H is the HEAD commit when you stashed
  • I records the index state
  • W records the working directory state

Handling Conflicts

When applying a stash causes conflicts:
1
Git marks conflicts
2
$ git stash pop
Auto-merging file.txt
CONFLICT (content): Merge conflict in file.txt
3
Resolve conflicts manually
4
Edit files and remove conflict markers:
5
<<<<<<< Updated upstream
Current version
=======
Stashed version
>>>>>>> Stashed changes
6
Mark as resolved
7
git add file.txt
8
If you used pop, drop the stash manually
9
git stash drop
If conflicts occur with git stash pop, the stash is NOT automatically dropped. You must drop it manually after resolving conflicts.

Export and Import Stashes

Export Stashes

# Export all stashes to a reference
git stash export --to-ref refs/stash-backup

# Export to print (for sharing)
git stash export --print

Import Stashes

# Import stashes from a commit
git stash import <commit-hash>

Recovering Dropped Stashes

If you accidentally dropped a stash:
# Find unreachable stash commits
git fsck --unreachable | grep commit | cut -d\  -f3 | \
  xargs git log --merges --no-walk --grep=WIP

# Apply a recovered stash
git stash apply <commit-hash>

Stash vs. Other Approaches

ApproachProsCons
StashQuick, non-intrusiveCan be forgotten, conflicts possible
WIP CommitPart of history, easy to referenceClutters history, requires reset
Temporary BranchClean separationMore steps, branch management

Best Practices

  1. Use descriptive messages - git stash push -m "..." helps identify stashes later
  2. Don’t accumulate stashes - Apply or drop stashes regularly. More than 3-4 stashes indicates workflow issues
  3. Include untracked files when needed - Use -u to avoid losing new files
  4. Prefer pop over apply - This automatically cleans up applied stashes
  5. Consider WIP commits for long-term storage - Stashes are meant to be temporary
  6. Review stashes before applying - Use git stash show -p to avoid surprises

Common Issues

Stash Not Showing All Changes

You likely have untracked files. Use:
git stash -u

Can’t Pop Stash Due to Conflicts

Use apply instead, resolve conflicts, then drop manually:
git stash apply
# Resolve conflicts
git stash drop

Lost a Stash After Clear

Recovery is possible but complex:
git fsck --unreachable | grep commit | cut -d\  -f3 | \
  xargs git log --merges --no-walk --grep=WIP

Configuration

Useful stash configurations:
[stash]
    # Show diff stats after stash show
    showStat = true
    
    # Show patch after stash show
    showPatch = true
    
    # Include untracked files by default
    showIncludeUntracked = true

[alias]
    # Quick stash with message
    st = stash push -u -m
    
    # List stashes with details
    stashes = stash list --format='%gd: %s [%cr]'

Build docs developers (and LLMs) love