stash Git Command Guide
The git stash command temporarily shelves (or stashes) changes you’ve made to your working copy so you can work on something else, and then come back and re-apply them later. Stashing is useful when you need to switch contexts quickly without committing incomplete work.
git stash Syntax:
Section titled “git stash Syntax:”git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all] [-m|--message <message>] [--pathspec-from-file=<file> [--pathspec-file-nul]] [--] [<pathspec>...]]git stash show [-u|--include-untracked|--only-untracked] [<diff-options>] [<stash>]git stash drop [-q|--quiet] [<stash>]git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]git stash branch <branchname> [<stash>]git stash [save [--patch] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all] [-m|--message <message>] [--pathspec-from-file=<file> [--pathspec-file-nul]] [--] [<pathspec>...]]git stash cleargit stash create [<message>]git stash store [-m|--message <message>] [-q|--quiet] <commit>Stash Creation Options:
Section titled “Stash Creation Options:”| Option | Description |
|---|---|
-p, --patch | Interactively select hunks to stash |
-k, --keep-index | Keep staged changes in index |
--no-keep-index | Don’t keep staged changes |
-u, --include-untracked | Include untracked files |
-a, --all | Include untracked and ignored files |
-m <message>, --message <message> | Add descriptive message |
-q, --quiet | Suppress status messages |
Stash Display Options:
Section titled “Stash Display Options:”| Option | Description |
|---|---|
--stat | Show diff statistics |
--name-only | Show only changed filenames |
--name-status | Show filenames with status |
-p, --patch | Show full diffs |
-u, --include-untracked | Show untracked files in stash |
--only-untracked | Show only untracked files |
Stash Management Options:
Section titled “Stash Management Options:”| Option | Description |
|---|---|
--index | Try to recreate staged state |
-q, --quiet | Suppress status messages |
Parameters:
Section titled “Parameters:”| Parameter | Description |
|---|---|
<stash> | Stash reference (stash@{0}, stash@{1}, etc.) |
<branchname> | Name for new branch |
<message> | Descriptive message for stash |
<pathspec> | Limit operation to specific paths |
Understanding Stash Concepts:
Section titled “Understanding Stash Concepts:”Stash Storage:
Section titled “Stash Storage:”Stash Structure:├── Stash Entry: Complete snapshot of working directory state├── Index State: What was staged before stashing├── Working Tree: Unstaged changes├── Untracked Files: Optionally included files└── Message: Optional description
Stash References:├── stash@{0}: Most recent stash├── stash@{1}: Second most recent├── stash@{n}: Nth stash from top└── stash@{/pattern}: Search by message patternStash vs Other Operations:
Section titled “Stash vs Other Operations:”Comparison Matrix:├── Stash: Temporary storage, preserves working state├── Commit: Permanent history, requires clean message├── Branch: Parallel development, full isolation├── Reset: Discards changes, cannot recover easily└── Shelve: Similar to stash (other VCS systems)Basic Stash Operations:
Section titled “Basic Stash Operations:”Creating Stashes:
Section titled “Creating Stashes:”# Stash all changes (staged + unstaged)git stash
# Stash with descriptive messagegit stash push -m "WIP: user authentication feature"
# Stash only unstaged changes, keep stagedgit stash push --keep-index
# Stash interactively (select hunks)git stash push --patch
# Include untracked filesgit stash push --include-untracked
# Include untracked and ignored filesgit stash push --allViewing Stashes:
Section titled “Viewing Stashes:”# List all stashesgit stash list
# Show stash contents (diff)git stash show
# Show specific stashgit stash show stash@{1}
# Show stash with full diffgit stash show -p stash@{2}
# Show stash statisticsgit stash show --statApplying Stashes:
Section titled “Applying Stashes:”# Apply most recent stashgit stash pop
# Apply specific stashgit stash apply stash@{1}
# Apply and preserve stashgit stash apply stash@{0}
# Apply with index reconstructiongit stash pop --indexManaging Stashes:
Section titled “Managing Stashes:”# Delete most recent stashgit stash drop
# Delete specific stashgit stash drop stash@{2}
# Delete all stashesgit stash clear
# Create branch from stashgit stash branch feature-fix stash@{1}Advanced Stash Scenarios:
Section titled “Advanced Stash Scenarios:”Selective Stashing:
Section titled “Selective Stashing:”# Stash specific filesgit stash push -- src/main.c src/utils.h
# Stash by path patterngit stash push -- '*.log' 'build/'
# Interactive hunk selectiongit stash push --patch# Then use 'y' to stash, 'n' to skip, 's' to split hunksStash with Untracked Files:
Section titled “Stash with Untracked Files:”# Include newly created filesgit stash push --include-untracked
# Include everything (tracked, untracked, ignored)git stash push --all
# Show untracked files in stashgit stash show --include-untracked
# Show only untracked filesgit stash show --only-untrackedStash Message Patterns:
Section titled “Stash Message Patterns:”# Descriptive messagesgit stash push -m "Bug fix: login validation"git stash push -m "Feature: user profile page"git stash push -m "Refactor: database connection pooling"
# Search stashes by messagegit stash list | grep "login"git stash show stash@{/login}Index Preservation:
Section titled “Index Preservation:”# Keep staged changes when stashinggit stash push --keep-index
# Apply stash without touching indexgit stash apply --index
# Check what's staged vs unstagedgit diff --cached # Staged changesgit diff # Unstaged changesConfiguration and Best Practices:
Section titled “Configuration and Best Practices:”Git Configuration for Stash:
Section titled “Git Configuration for Stash:”# Configure stash behaviorgit config stash.showStat true # Show stats by defaultgit config stash.showPatch true # Show patch by defaultgit config stash.showUntrackedFiles true # Show untracked files
# Configure stash messagesgit config stash.useBuiltin true # Use modern stash implementation
# Configure colorsgit config color.stash.branch yellowgit config color.stash.added greengit config color.stash.changed redStash Best Practices:
Section titled “Stash Best Practices:”# Use descriptive messagesgit stash push -m "WIP: implement user auth"
# Don't stash instead of committing# Use stash for temporary context switches
# Clean up regularlygit stash listgit stash drop <old-stashes>
# Use stash branches for complex workgit stash branch feature-fix stash@{0}Safe Stash Operations:
Section titled “Safe Stash Operations:”# Check before applyinggit stash show stash@{0} --stat
# Backup important stashesgit stash show stash@{0} -p > important-changes.patch
# Verify clean applicationgit status # Should show clean working treeIntegration with Development Workflows:
Section titled “Integration with Development Workflows:”Context Switching Workflow:
Section titled “Context Switching Workflow:”#!/bin/bash# Quick context switching with stash
switch_context() { local task_description="$1"
# Stash current work if ! git diff --quiet || ! git diff --cached --quiet; then git stash push -m "Context switch: $task_description" echo "Work stashed for: $task_description" fi
# Switch to other task # ... work on other task ...
# Later: restore work # git stash pop}
# Usageswitch_context "urgent bug fix"Emergency Fix Workflow:
Section titled “Emergency Fix Workflow:”# Handle emergency fixesemergency_fix() { local fix_branch="hotfix/emergency"
# Stash current work git stash push -m "Emergency fix - stashed work"
# Create fix branch from main git checkout main git pull origin main git checkout -b "$fix_branch"
# Make emergency fix # ... edit files ... git add . git commit -m "Emergency fix: [description]"
# Deploy and merge git checkout main git merge "$fix_branch" git push origin main
# Restore original work git checkout original-branch git stash pop
echo "Emergency fix completed, work restored"}Stash-Based Code Review:
Section titled “Stash-Based Code Review:”# Prepare changes for reviewprepare_review() { local review_branch="review/$(date +%Y%m%d-%H%M%S)"
# Stash current changes git stash push -m "Code review preparation"
# Create review branch git checkout -b "$review_branch"
# Apply stashed changes git stash pop
# Clean up and prepare git add . git commit -m "Changes ready for review"
# Push for review git push -u origin "$review_branch"
echo "Changes prepared for review on branch: $review_branch"}Troubleshooting Common Issues:
Section titled “Troubleshooting Common Issues:”Stash Application Conflicts:
Section titled “Stash Application Conflicts:”# Handle conflicts during apply/popgit stash pop # May cause conflicts
# Resolve conflicts manually# Edit conflicted files# Stage resolved filesgit add resolved-file.txt
# Complete the stash applicationgit commit # Creates merge commit
# Or abort and try different approachgit reset --merge # Abort conflicted mergegit stash apply # Try apply instead of popLost Stash Recovery:
Section titled “Lost Stash Recovery:”# Find dropped stashesgit fsck --unreachable | grep commit
# Recover specific commitgit show <commit-hash>git cherry-pick <commit-hash> # If you want to apply it
# Use reflog to find stash operationsgit reflog | grep stashStash with Binary Files:
Section titled “Stash with Binary Files:”# Handle binary files in stashgit stash push --all # Include everything
# Check binary files in stashgit stash show --name-only | file -
# Apply carefully (binaries may conflict)git stash show -p | head -50 # Preview before applyingStash Performance Issues:
Section titled “Stash Performance Issues:”# Speed up stash operations in large reposgit stash push --quiet # Reduce output
# Limit stash scopegit stash push -- <specific-path>
# Use shallow stashes for quick savesgit stash push -m "quick save"Encoding and Character Issues:
Section titled “Encoding and Character Issues:”# Handle encoding problemsgit config core.quotepath false
# Fix line ending issuesgit config core.autocrlf input
# Handle special characters in stash messagesgit stash push -m "Fix: encoding issue with ümlauts"Stash in Submodules:
Section titled “Stash in Submodules:”# Handle stashes in submodule repositoriesgit submodule foreach 'git stash push -m "parent project changes"'
# Apply stashes in submodulesgit submodule foreach git stash pop
# Check submodule stash statusgit submodule foreach git stash listReal-World Usage Examples:
Section titled “Real-World Usage Examples:”Development Workflow Integration:
Section titled “Development Workflow Integration:”#!/bin/bash# Integrated stash workflow
dev_workflow_stash() { echo "=== Development Workflow with Stash ==="
# Check current status if git diff --quiet && git diff --cached --quiet; then echo "✓ Working tree is clean" return 0 fi
# Categorize changes staged=$(git diff --cached --name-only | wc -l) unstaged=$(git diff --name-only | wc -l) untracked=$(git status --porcelain | grep "^??" | wc -l)
echo "Changes detected:" echo " Staged files: $staged" echo " Unstaged files: $unstaged" echo " Untracked files: $untracked"
# Intelligent stashing if [ "$staged" -gt 0 ] && [ "$unstaged" -eq 0 ]; then echo "Only staged changes - committing instead" git commit -m "WIP: staged changes" elif [ "$unstaged" -gt 0 ] && [ "$untracked" -eq 0 ]; then git stash push -m "WIP: unstaged changes" echo "✓ Unstaged changes stashed" elif [ "$untracked" -gt 0 ]; then git stash push --include-untracked -m "WIP: with untracked files" echo "✓ Changes stashed including untracked files" else git stash push -m "WIP: mixed changes" echo "✓ Mixed changes stashed" fi
echo "Ready for context switch"}
dev_workflow_stashStash-Based Feature Development:
Section titled “Stash-Based Feature Development:”# Feature development with stash checkpointsfeature_development() { local feature_name="$1"
echo "Starting feature development: $feature_name"
# Create feature branch git checkout -b "feature/$feature_name"
# Development loop with stash checkpoints while true; do echo "Working on $feature_name..." # ... development work ...
read -p "Create checkpoint? (y/n/q): " choice case "$choice" in y|Y) git stash push -m "Checkpoint: $(date) - $feature_name" echo "✓ Checkpoint created" ;; q|Q) break ;; *) continue ;; esac done
# Review checkpoints echo "Feature checkpoints:" git stash list | grep "$feature_name"
# Apply final state git stash pop # Apply most recent echo "Feature development complete"}
feature_development "user-dashboard"Automated Testing with Stash:
Section titled “Automated Testing with Stash:”# Test changes without committingtest_with_stash() { echo "Testing changes with stash isolation"
# Stash current work git stash push -m "Testing: $(date)"
# Run tests on clean state if ./run-tests.sh; then echo "✓ Tests passed on clean state" else echo "✗ Tests failed on clean state" return 1 fi
# Apply changes and test again git stash pop
if ./run-tests.sh; then echo "✓ Tests passed with changes" else echo "⚠ Tests failed with changes - review needed" return 1 fi
echo "Testing complete"}
test_with_stashCollaborative Stash Management:
Section titled “Collaborative Stash Management:”# Team stash coordinationteam_stash_workflow() { echo "=== Team Stash Workflow ==="
# Check team stash status echo "Team stash overview:" git stash list --format="%gd: %gs (%cr)" | head -10
# Identify stashes by team member echo "Stashes by team member:" git stash list | while read -r line; do hash=$(echo "$line" | cut -d: -f1) author=$(git show --format='%an' --no-patch "$hash") message=$(git show --format='%s' --no-patch "$hash") echo "$author: $message" done | sort | uniq -c | sort -nr
# Find old stashes to clean up echo "Potentially stale stashes (>30 days):" git stash list --format="%gd: %gs (%cr)" | while read -r line; do age=$(echo "$line" | grep -o "[0-9]\+ days ago\|[0-9]\+ weeks ago\|[0-9]\+ months ago" || echo "") if [[ "$age" == *"month"* ]] || [[ "$age" == *"week"* && "$age" > "4 weeks ago" ]]; then echo "$line" fi done
echo "Team stash review complete"}
team_stash_workflowStash Analytics and Reporting:
Section titled “Stash Analytics and Reporting:”# Analyze stash usage patternsstash_analytics() { echo "=== Stash Usage Analytics ==="
# Stash statistics total_stashes=$(git stash list | wc -l) echo "Total stashes: $total_stashes"
# Stash frequency echo "Stash creation timeline:" git stash list --format='%ai' | cut -d' ' -f1 | sort | uniq -c
# Most common stash messages echo "Common stash topics:" git stash list --format='%s' | sed 's/WIP:\|TODO:\|FIX://' | sort | uniq -c | sort -nr | head -10
# Stash size analysis echo "Stash sizes (lines changed):" git stash list --format='%gd' | while read -r stash; do lines=$(git stash show --stat "$stash" | tail -1 | awk '{print $4+$6}') echo "$stash: $lines lines" done | sort -k2 -nr | head -10
# Author analysis echo "Stash authors:" git stash list --format='%H %an' | while read -r hash author; do echo "$author" done | sort | uniq -c | sort -nr
echo "Analytics complete"}
stash_analyticsWhat’s the difference between git stash pop and git stash apply?
Section titled “What’s the difference between git stash pop and git stash apply?”git stash pop applies the stash and removes it from the stash list; git stash apply applies the stash but keeps it in the list for potential re-application.
How do I stash untracked files?
Section titled “How do I stash untracked files?”Use git stash push —include-untracked to stash untracked files, or —all to include untracked and ignored files.
Can I stash only specific files?
Section titled “Can I stash only specific files?”Yes, use git stash push —
How do I see what’s in a stash without applying it?
Section titled “How do I see what’s in a stash without applying it?”Use git stash show to see a summary, or git stash show -p for the full diff.
What happens if I stash with staged changes?
Section titled “What happens if I stash with staged changes?”By default, staged changes become unstaged when you apply the stash. Use —index when applying to restore the staged state.
Can I create a branch from a stash?
Section titled “Can I create a branch from a stash?”Yes, use git stash branch
How do I recover a dropped stash?
Section titled “How do I recover a dropped stash?”Use git fsck —unreachable | grep commit to find dropped stashes, then git show
What’s the difference between stash save and stash push?
Section titled “What’s the difference between stash save and stash push?”stash push is the modern command (since Git 2.13); stash save is the older deprecated syntax.
Can I stash in the middle of a merge conflict?
Section titled “Can I stash in the middle of a merge conflict?”No, you must resolve the merge first. Stash only works on a clean working tree state.
How do I see stash statistics?
Section titled “How do I see stash statistics?”Use git stash show —stat to see how many files and lines changed in a stash.
Can stashes be shared between repositories?
Section titled “Can stashes be shared between repositories?”No, stashes are local to each repository and don’t transfer with push/pull operations.
How do I search stashes by message?
Section titled “How do I search stashes by message?”Use git stash list and pipe to grep, or use stash@{/pattern} syntax for direct reference.
What’s the stash stack order?
Section titled “What’s the stash stack order?”stash@{0} is the most recent, stash@{1} is the second most recent, and so on.
Can I modify a stash without applying it?
Section titled “Can I modify a stash without applying it?”No, stashes are immutable. To modify, apply the stash, make changes, then create a new stash.
How do I handle stashes with binary files?
Section titled “How do I handle stashes with binary files?”Stashes work with binary files, but conflicts may be harder to resolve. Use —stat to check stash contents before applying.
What’s the performance impact of stashing in large repos?
Section titled “What’s the performance impact of stashing in large repos?”Stashing is generally fast, but showing large stashes with -p can be slow. Use —stat for quick overview.
Can I use stash with submodules?
Section titled “Can I use stash with submodules?”Yes, but stashes in submodules are separate. Use git submodule foreach to manage stashes across all submodules.
How do I automate stash cleanup?
Section titled “How do I automate stash cleanup?”Create a cron job or hook that runs git stash list and drops stashes older than a certain age.
What’s the difference between stash and shelve?
Section titled “What’s the difference between stash and shelve?”Stash is Git’s built-in feature; shelve is similar functionality in other version control systems like Perforce.
Applications of the git stash command
Section titled “Applications of the git stash command”- Context Switching: Temporarily save work to switch to urgent tasks
- Code Review Preparation: Clean working tree for reviewing others’ changes
- Experimental Development: Try ideas without committing incomplete work
- Emergency Fixes: Quick switches to hotfix branches
- Branch Management: Clean switches between feature branches
- Testing Isolation: Test changes without affecting main development
- Collaborative Development: Share work-in-progress without premature commits
- Workflow Flexibility: Enable fluid development processes