Skip to content

Advanced Git Stash — Partial Stashes, Branches, and Recovery

DodaTech 5 min read

In this tutorial, you'll learn about Advanced Git Stash. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

What You'll Learn

Go beyond git stash and stash pop — use partial stashes, stash individual hunks, create branches from stashes, recover dropped stashes, and automate stash workflows in Git.

Why It Matters

Basic stash works for simple "save all, restore all" scenarios. Advanced stash techniques let you save only specific files, stash different changes to different branches, and recover from mistakes — turning stash into a precision tool.

Real-World Use

You have three unrelated changes in your working directory (a CSS tweak, a database Migration, and a bug fix). You need to stash each independently so you can open separate branches. Advanced stash makes this possible.

Partial File Stashing

Save only specific files while leaving others untouched:

# Working on login.py, style.css, and database.py
git status
# modified:   login.py
# modified:   style.css
# modified:   database.py

# Stash only CSS and HTML files
git stash push -m "UI changes" -- *.css *.html
# Saved working directory and index state On main: UI changes

# Only login.py and database.py remain modified
git status
# modified:   login.py
# modified:   database.py

# Stash the database changes separately
git stash push -m "DB migration" -- database.py
# Saved working directory and index state On main: DB migration

# Now only login.py is modified
git status
# modified:   login.py

Interactive Hunk Stashing

Choose which hunks to stash, hunk by hunk:

# Stash interactively
git stash push -p
# Diff divided into hunks. For each hunk:
# (1) yes / (2) no / (3) edit / (4) quit / (5) all / (6) help

# Example:
# diff --git a/login.py b/login.py
# @@ -10,5 +10,8 @@ def login():
#     verify_password()
# +    send_welcome_email()     # ← Hunk 1
# +    log_attempt()             # ← Hunk 2
# Stash this hunk? [y,n,q,a,d,e,?] y    # Stash hunk 1
# Stash this hunk? [y,n,q,a,d,e,?] n    # Keep hunk 2 in working dir

Keep Index Stashing

Stash unstaged changes but keep staged changes intact:

# Stage some changes, leave others unstaged
git add login.py           # Staged
echo "debug" >> utils.py   # Unstaged

# Stash only unstaged changes
git stash push -k -m "WIP utils debug"
# --keep-index keeps staged files (login.py) in the working tree
# Only utils.py changes are stashed

git status
# modified:   login.py     # Still staged as before

# Restore the unstashed changes
git stash pop
# utils.py changes are back

Creating a Branch from a Stash

When a stash conflicts with the current branch state:

# Current branch has diverged since the stash was created
git stash list
# stash@{0}: WIP on feature: a1b2c3 Add login form

# Trying to pop causes conflicts
git stash pop
# CONFLICT (content): Merge conflict in login.py

# Instead, create a branch from the commit where stash was made
git stash branch new-feature stash@{0}
# Switched to a new branch 'new-feature'
# On branch new-feature
# Changes to be committed:
#   modified:   login.py

# The stash is automatically dropped if successful

Viewing Stash Contents

# List all stashes
git stash list
# stash@{0}: On main: DB migration
# stash@{1}: On main: UI changes
# stash@{2}: WIP on feature: a1b2c3

# Show summary of what's in a stash
git stash show stash@{1}
# style.css | 15 +++++++++++++++
# 1 file changed, 15 insertions(+)

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

# Show as a patch
git stash show -v stash@{1}

Recovering Dropped Stashes

# Accidentally dropped a stash
git stash drop stash@{1}
# Dropped stash@{1} (a1b2c3d4e5f6...)

# Use reflog to find the commit
git reflog show refs/stash
# a1b2c3 refs/stash@{0}: WIP on main: UI changes
# d4e5f6 refs/stash@{1}: WIP on main: DB migration  ← still in reflog

# Recover by applying the commit directly
git stash apply d4e5f6
# Changes restored as if you did git stash pop

Stashing Untracked and Ignored Files

# Default: stash only tracked, modified files
git stash

# Include untracked files (new files not yet tracked)
git stash --include-untracked   # or -u

# Include everything (including .gitignore'd files)
git stash --all                 # or -a
# WARNING: -a stashes everything including node_modules, .env, etc.

Automated Stash Workflow

# Before switching branches, auto-stash
#!/bin/bash
# git-switch-safe: stash changes, switch branch, pop stash
BRANCH=$1
CURRENT=$(git branch --show-current)

if [ -n "$(git status --porcelain)" ]; then
    git stash push -m "Auto-stash from $CURRENT"
    STASHED=true
fi

git checkout "$BRANCH"

if [ "$STASHED" = true ]; then
    git stash pop
fi

Common Pitfalls

Mistake Solution
Stash pop causes conflicts Use git stash branch instead
Lost stash after drop Check git reflog show refs/stash
Stashed too many changes at once Use -p for interactive, or push -- <path> for partial
Untracked files missing from stash Add -u or -a depending on need

Practice Questions

  1. How do you stash only CSS files while leaving Python files in the working directory?
  2. What command creates a new branch from a stash that avoids conflicts?
  3. How can you recover a stash after running git stash drop?

FAQs

Is there a limit to how many stashes I can have?

Stashes are stored as refs in .git/refs/stash — there is no hard limit, but performance degrades with hundreds of stashes. Keep your stash list short by applying or dropping stashes regularly.

Can I stash only staged changes?

No direct option, but you can work around it: stage your files, then run git stash push --staged (Git 2.35+). For older versions, use git stash push -k to keep index and stash unstaged only, or commit staged changes temporarily.

Does git stash work with untracked files created by tools?

By default, no — only tracked files are stashed. Use -u to include untracked files or -a to include everything including ignored files. Be careful with -a as it stashes large directories like node_modules.

Next Steps

After mastering advanced stash techniques, use Git Worktrees to avoid stashing entirely, or learn interactive rebase to clean up commit history before merging.


Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro