GitListing Stashes (stash list)

Listing Stashes (git stash list)

A stash you can't find is a stash you've lost. git stash list shows your stack and is the first command you should run before popping, applying, or dropping anything. Combined with git stash show, you can fully inspect a stash without touching your working tree.

The basic list

What the stack looks like

Bash
git stash list
# stash@{0}: On feature/login: WIP login validation
# stash@{1}: On main: hotfix scratch
# stash@{2}: WIP on feature/cart: 3f2a1b9 Wire totals
How to read an entry

Every line has three parts: the stash ref, the branch context, and the message.

Anatomy of a stash line

Text
stash@{0}: On feature/login: WIP login validation
└──┬───┘  └──────┬───────┘  └────────┬───────────┘
   │             │                   │
   ref           branch you were on  message (yours or auto-generated)
   (index in     when you stashed
    the stack)
  • stash@{0} is always the most recent stash.

  • The number is an index, not an ID. After you drop stash@{1}, what was stash@{2} becomes stash@{1}.

  • If you used -m, your message replaces the default WIP on <branch>: <hash> <subject>.

Stash refs are not stable
Don't paste `stash@2` into a script and assume it'll point to the same thing tomorrow. If you must reference a specific stash long-term, grab its raw SHA from `git rev-parse stash@2` — that doesn't move.
Inspecting what's inside

Summary first, then full diff

Bash
# File-by-file summary of the top stash
git stash show
#  src/login.js  | 14 ++++++++++++--
#  src/auth.js   |  3 +++
#  2 files changed, 15 insertions(+), 2 deletions(-)

# Full diff
git stash show -p
# diff --git a/src/login.js b/src/login.js
# ...

# Inspect a specific stash
git stash show stash@{2}
git stash show -p stash@{2}
Just show the file names

--name-only and --name-status

Bash
git stash show --name-only
# src/login.js
# src/auth.js

git stash show --name-status
# M  src/login.js
# A  src/new-file.js
Pretty formats

Add author and timestamps

Bash
git stash list --pretty=format:"%gd %ci %s"
# stash@{0} 2024-04-15 09:42:11 +0100  On feature/login: WIP login validation
# stash@{1} 2024-04-14 16:08:55 +0100  On main: hotfix scratch

# Or use a familiar log format
git stash list --date=relative --pretty=format:"%gd %cr  %s"
# stash@{0} 3 hours ago   On feature/login: WIP login validation
# stash@{1} 1 day ago     On main: hotfix scratch

Useful placeholders: %gd (stash ref), %s (subject), %ci (commit date ISO), %cr (relative date), %an (author), %H (full hash).

A useful alias

Make "git stashes" show useful columns

Bash
git config --global alias.stashes \
  "stash list --date=relative --pretty=format:'%gd  %cr  %s'"

git stashes
# stash@{0}  3 hours ago   On feature/login: WIP login validation
# stash@{1}  1 day ago     On main: hotfix scratch
Empty list

No output? That's the message.

Bash
git stash list
# (nothing)

# Compare with explicit confirmation:
git stash list && echo "(no stashes)"

git stash list prints nothing when the stack is empty. It does not error.

Inspect before you pop
Tip
Always run `git stash show -p stash@{N}` before popping an old stash. Things change while a stash sits on the shelf — a quick diff preview tells you whether it will apply cleanly and whether it's still relevant.
Real-world recipe: triaging old stashes

Friday afternoon cleanup

Bash
git stash list --date=relative --pretty=format:"%gd  %cr  %s"

# Anything older than ~a week, decide: keep, promote, or drop.
git stash show -p stash@{4}    # peek
git stash branch save/old-cart-work stash@{4}   # promote to a branch
git stash drop stash@{3}        # not needed
Stash list reads the reflog, not the tree
Internally, the stash stack is just the reflog of the `refs/stash` ref. That's why dropped stashes can sometimes be recovered through `git reflog` — more on that in the "Dropping Stashes" chapter.