Staging & Stashing
Master the Git staging area and stash functionality for flexible workflow management and temporary storage.
Understanding the Staging Area
The Index Concept
The staging area (also called "index") is Git's preparation area for commits:
# Three states of files:
# Working Directory → Staging Area → Repository
# Check current state
git status
git status -s # Short format
# See what's staged vs unstaged
git diff # Working directory vs staging area
git diff --staged # Staging area vs last commit
git diff --cached # Same as --staged
Advanced Staging
Interactive Staging
# Interactive add mode
git add -i
# Patch mode (choose hunks)
git add -p filename.txt
git add --patch filename.txt
# Interactive options:
# y - stage this hunk
# n - don't stage this hunk
# q - quit, don't stage this or remaining hunks
# a - stage this and all remaining hunks
# d - don't stage this or remaining hunks
# s - split current hunk into smaller hunks
# e - manually edit the current hunk
Selective Staging
# Stage specific files
git add file1.txt file2.txt
# Stage by pattern
git add "*.js"
git add src/
# Stage all modified files (not new files)
git add -u
git add --update
# Stage all changes (including new files)
git add -A
git add --all
# Stage and remove deleted files
git add . # Handles all changes including deletions
Partial File Staging
# Stage specific lines within a file
git add -p filename.txt
# Split hunks for more granular control
# In patch mode: 's' to split, 'e' to edit
# Stage specific lines using editor
git add -e filename.txt
# View what's staged for specific file
git diff --staged filename.txt
Interactive Staging Commands
# Enter interactive mode
git add -i
# Available commands in interactive mode:
# 1: status - show paths with changes
# 2: update - add working tree state to index
# 3: revert - revert staged set back to working tree
# 4: add untracked - add untracked paths to index
# 5: patch - pick hunks and update selectively
# 6: diff - view diff between HEAD and index
# 7: quit - exit interactive mode
# 8: help - show help
Stashing Changes
Basic Stash Operations
# Stash current changes
git stash
git stash save # Same as above (older syntax)
# Stash with message
git stash save "Work in progress on feature X"
git stash push -m "Work in progress on feature X" # Modern syntax
# Include untracked files
git stash -u
git stash --include-untracked
# Include ignored files too
git stash -a
git stash --all
# List all stashes
git stash list
Applying Stashes
# Apply most recent stash
git stash apply
# Apply and remove from stash list
git stash pop
# Apply specific stash
git stash apply stash@{2}
git stash pop stash@{1}
# Apply stash to different branch
git stash branch new-branch-name stash@{1}
Stash Management
# Show stash contents
git stash show
git stash show -p # Show full diff
git stash show stash@{1}
# Drop stashes
git stash drop # Drop most recent
git stash drop stash@{2} # Drop specific stash
# Clear all stashes
git stash clear
# Create stash without removing changes
git stash store $(git stash create)
Advanced Stash Operations
# Stash specific files only
git stash push filename.txt
git stash push src/ tests/
# Stash with pathspec
git stash push -m "Stash JS files" -- "*.js"
# Stash keeping index (staged files remain staged)
git stash --keep-index
git stash -k
# Interactive stashing
git stash -p
git stash --patch
# Stash including ignored files
git stash --all
Working with Multiple Stashes
Stash Naming and Organization
# Create named stashes
git stash save "Feature X: halfway through implementation"
git stash push -m "Bug fix: temporary debugging code"
git stash push -m "Experiment: trying new approach"
# List stashes with details
git stash list --stat
git stash list --oneline
# Show specific stash details
git stash show stash@{0}
git stash show stash@{0} --stat
git stash show stash@{0} -p
Stash Workflow Patterns
# Quick branch switching workflow
git stash # Save current work
git switch main # Switch to main
git pull origin main # Get updates
git switch feature-branch # Back to feature
git stash pop # Continue work
# Experiment workflow
git stash push -m "Current stable state"
# Try experimental changes...
git stash # If experiment fails
git stash pop stash@{1} # Restore stable state
# Or if experiment succeeds:
git stash drop stash@{1} # Remove old stable state
Stash Inspection
# Compare stashes
git diff stash@{0} stash@{1}
# See what files are in stash
git stash show --name-only stash@{0}
# Check stash against current HEAD
git diff stash@{0}
# View stash like a commit
git show stash@{0}
git log --oneline stash@{0}
Advanced Staging Scenarios
Staging vs Working Directory Management
# Stage file then continue editing
git add filename.txt # Stage current state
# Edit file more...
git diff filename.txt # See unstaged changes
git diff --staged filename.txt # See staged changes
# Commit staged version, keep working on unstaged
git commit -m "Stable version"
# Continue with unstaged changes
Partial Commits
# Create multiple commits from one modified file
git add -p largefile.txt # Stage some hunks
git commit -m "First logical change"
git add -p largefile.txt # Stage more hunks
git commit -m "Second logical change"
Staging Deleted Files
# When files are deleted outside Git
git add -u # Stage deletions
git status # Confirm deletions are staged
# Stage specific deletion
git rm filename.txt # Remove and stage deletion
git add filename.txt # Stage deletion if file already removed
Staging Best Practices
Atomic Commits
# Stage related changes together
git add feature-related-file1.js feature-related-file2.js
git commit -m "Implement user authentication feature"
# Use interactive staging for precision
git add -p complex-file.js # Choose only related changes
git commit -m "Fix specific bug in validation"
Review Before Commit
# Always review what's staged
git status
git diff --staged
# Check specific file that's staged
git diff --staged filename.txt
# See summary of staged changes
git diff --staged --stat
Staging Workflow
# Recommended workflow
git status # See what's changed
git diff # Review unstaged changes
git add -p # Selectively stage
git diff --staged # Review staged changes
git commit -m "Descriptive message"
git status # Confirm clean state
Stash Best Practices
When to Stash
# Good times to stash:
# - Quick branch switch needed
# - Pull updates with local changes
# - Experiment with different approach
# - Emergency bug fix interruption
git stash push -m "WIP: feature development"
git switch hotfix-branch
# Fix urgent issue...
git switch feature-branch
git stash pop
Stash Hygiene
# Regular stash cleanup
git stash list # Review old stashes
git stash show stash@{2} # Check if still needed
git stash drop stash@{2} # Remove if not needed
# Don't let stashes accumulate
git stash list | wc -l # Count stashes
# Keep only 2-3 recent stashes
Stash vs Commit
# Use stash for:
# - Temporary, incomplete work
# - Quick context switching
# - Experimental changes
# Use commit for:
# - Completed logical changes
# - Work you want to track in history
# - Changes ready for sharing
# Convert stash to commit if work becomes significant
git stash pop
git add .
git commit -m "Implement feature X"
Troubleshooting Staging and Stashing
Common Staging Issues
# File not staging properly
git status -u # Check if file is ignored
git check-ignore filename.txt
git add -f filename.txt # Force add if ignored
# Accidentally staged wrong changes
git reset HEAD filename.txt # Unstage file
git restore --staged filename.txt # Modern syntax
# Staged changes disappeared
git diff --staged # Check if still staged
git reflog # Check for accidental resets
Common Stash Issues
# Stash apply conflicts
git stash apply # Try to apply
# If conflicts occur:
git status # See conflicted files
# Resolve conflicts manually
git add resolved-file.txt
# Don't need to commit, conflicts are in working directory
# Can't pop stash due to conflicts
git stash apply stash@{0} # Apply without removing from stash
# Resolve conflicts
git stash drop stash@{0} # Manually remove from stash
# Lost stash reference
git fsck --unreachable | grep commit | cut -d\ -f3 | xargs git log --merges --no-walk --grep=WIP
Recovery Procedures
# Recover accidentally dropped stash
git fsck --no-reflog | awk '/dangling commit/ {print $3}'
git show <commit-hash> # Check if it's your stash
git stash apply <commit-hash>
# Recover overwritten changes
git reflog # Find previous state
git stash apply HEAD@{5} # Apply previous working directory state
Integration with Other Git Features
Stash and Rebase
# Stash before rebasing
git stash
git rebase main
git stash pop
# Handle rebase conflicts with stash
git rebase main
# If conflicts during rebase:
git stash # Stash any additional changes
# Resolve rebase conflicts
git rebase --continue
git stash pop # Restore additional changes
Stash and Merge
# Stash before merging
git stash
git merge feature-branch
git stash pop
# Selective stash for merge
git stash push -m "Changes not ready for merge" -- "*.temp"
git merge feature-branch
git stash pop # Restore temp changes after merge
Master staging and stashing before exploring Configuration and Collaboration.