Inspecting a stash before applying it Jump to heading

The stash list shows a one-line description per entry, usually “WIP on main: 8b3e4f2 some commit subject”. After a few days, nobody remembers which entry holds what. Applying the wrong one mixes unrelated changes into your working tree; applying the right one onto changed code produces conflicts you did not expect. Both are avoidable by looking first. A stash is a small group of commits — the working tree changes, the index state, and optionally the untracked files — and every normal inspection command works on them. This page shows how to read each part, compare a stash with your current work, and decide whether to apply, convert or drop it, within stashing and work-in-progress recovery.

When to use this approach Jump to heading

  • The stash list has several entries and you are not sure which one you need.
  • You are about to pop a stash onto a branch that has changed since it was made.
  • You want to clean up the stash list and need to know which entries are worth keeping.
  • A stash was recovered from dangling commits, as in recovering a dropped stash, and you need to confirm it is the right one.

Step 1 — List stashes with useful detail Jump to heading

The default list hides dates and file counts. Format it to show both.

git stash list --format='%gd  %cr  %gs'
# stash@{0}  2 hours ago   On feature/export: try batching
# stash@{1}  3 days ago    WIP on main: 4c2d9a1 Add search ranking
for s in $(git stash list --format=%gd); do
  printf '%-10s %3s files  %s\n' "$s" "$(git stash show --name-only "$s" | wc -l)" "$(git log -1 --format=%s "$s")"
done

Step 2 — Understand a stash’s structure Jump to heading

A stash commit has two or three parents, and each part answers a different question.

The parts of a stashThe stash commit itself records the working tree. Its first parent is the commit HEAD pointed to when the stash was made. Its second parent records the index, so staged changes can be told apart from unstaged ones. A third parent exists when untracked files were included.stash@{n}working tree statestash@{n}^1base commit(HEAD at the time)stash@{n}^2index (staged)stash@{n}^3untracked files(only with -u)every inspection command works on these, because they are ordinary commits
git log -1 --format='%h %s%nparents: %p' 'stash@{1}'
git rev-parse --verify -q 'stash@{1}^3' >/dev/null && echo "has untracked files"

Step 3 — Read the changes, staged and unstaged Jump to heading

git stash show -p shows the full diff between the base and the stashed working tree. To see what was staged separately, diff the index parent against the base.

git stash show -p 'stash@{1}'                         # everything, as a patch
git diff 'stash@{1}^1' 'stash@{1}^2'                  # only what was staged
git diff 'stash@{1}^2' 'stash@{1}'                    # only what was unstaged
git stash show --include-untracked --stat 'stash@{1}' # Git 2.32+: include new files
git show 'stash@{1}^3' --stat                         # any version: the untracked files

To look at one file as it was stashed, without applying anything:

git show 'stash@{1}:src/export/schedule.py' | less

Step 4 — Compare the stash with your current work Jump to heading

The question before applying is how the stash relates to where you are now. Two comparisons answer it: the files the stash touches that have changed on your branch since, and the full diff between the stashed tree and your current tree.

# Files the stash changes that have also changed on the branch since the stash's base
git diff --name-only 'stash@{1}^1' HEAD > /tmp/branch-changed
git stash show --name-only 'stash@{1}' > /tmp/stash-changed
sort /tmp/branch-changed /tmp/stash-changed | uniq -d       # likely conflict sites

# How the stashed version of a file differs from the current one
git diff HEAD 'stash@{1}' -- src/export/schedule.py
What to do with a stash after inspecting itIf none of its files changed on the branch since, apply or pop it directly. If several did, convert it to a branch at its base and integrate with a rebase. If its changes are already on the branch or no longer wanted, drop it.How does the stash relate to the branch now?no overlapApply / popclean apply likelyoverlapping filesstash branchthen rebasealready done or obsoleteDropgit stash drop'already done' is common — check with git diff HEAD stash@{n} before keeping it

If git diff HEAD 'stash@{1}' -- <file> shows nothing for every file the stash touches, the stashed changes are already on your branch and the stash can be dropped.

Step 5 — Apply without losing the stash, then drop deliberately Jump to heading

Prefer apply to pop for anything non-trivial. apply leaves the stash in the list, so if the result is wrong you can reset and try again; pop drops it as soon as the apply succeeds.

git stash apply --index 'stash@{1}'     # restore staged/unstaged split too
git status && git diff                  # check the result
git stash drop 'stash@{1}'              # only once you are satisfied

⚠️ SAFETY WARNING: If an apply goes wrong and you want to start over, git reset --hard discards the applied changes along with any uncommitted work you had before applying. Commit or stash your own work before applying an old stash. Because you used apply rather than pop, the stash itself is still there to apply again.

Apply, check, then dropApplying leaves the stash in the list while you check the working tree. If the result is right, you drop the stash explicitly. If not, you reset and the stash is still available, which pop would not allow once it had dropped the entry.youworking treestash liststash apply --indexstatus, diffdrop when satisfiedor reset, retrypop is apply plus an immediate drop — fine for quick stashes, risky for old ones

Validation checklist Jump to heading

Frequently Asked Questions Jump to heading

Why does git stash show not show staged and unstaged parts separately? Jump to heading

It diffs the stash against its base, combining both. The index is recorded in the second parent, so diffing ^1 against ^2 isolates the staged part.

Can I apply only part of a stash? Jump to heading

Yes: check out individual files from it with git checkout stash@{n} -- path, or apply the whole stash and discard unwanted hunks with git restore -p. The stash stays intact either way if you used apply.

Do stashes expire? Jump to heading

Stash entries live in the stash reflog, which follows gc.reflogExpire — ninety days by default — so very old stashes can disappear during garbage collection. Convert anything worth keeping into a branch.