Git Stash Is More Useful Than You Are Giving It Credit For

by Arif Ikhsanudin, Backend Developer

The One-Trick Usage

The typical use of git stash: you're halfway through something, a colleague asks you to look at a bug, and you need to switch branches without committing half-done work. You run git stash, switch branches, help with the bug, switch back, run git stash pop, and continue.

This is correct and useful. It's also the least interesting thing git stash can do.

What git stash Actually Does

git stash saves your working tree and index state to a stack of stashes, then resets your working tree to match HEAD. The stash stack is persistent — it survives branch switches, rebases, and session restarts. The entries in the stack are full Git objects stored in the repository.

The stack model means you can have multiple stashes simultaneously, each with its own saved state. Most developers treat it as a single-slot temporary buffer. It's actually a named stack.

Named Stashes

# Push with a descriptive message
git stash push -m "half-done payment retry, needs exponential backoff"

# Now if you stash something else:
git stash push -m "WIP: dashboard pagination experiment"

git stash list
# stash@{0}: On feature/dashboard: WIP: dashboard pagination experiment
# stash@{1}: On feature/payment: half-done payment retry, needs exponential backoff

Named stashes are recoverable weeks later. Anonymous stashes (git stash without a message) are recoverable too, but when you have five of them, "WIP on main" five times over is useless.

Applying Specific Stashes

# Apply without removing from the stack
git stash apply stash@{1}

# Apply and remove from the stack
git stash pop stash@{1}

# Show what's in a specific stash without applying
git stash show -p stash@{1}

The ability to apply a specific stash (not just the top of the stack) is what makes named stashes useful. You can stash an experiment on Monday, stash a different WIP on Wednesday, and apply either one on Friday.

Stashing Untracked and Ignored Files

By default, git stash only saves tracked files. New files you haven't added yet are left in the working tree.

# Stash tracked files AND untracked (new) files
git stash push -u -m "includes new files"
# or
git stash push --include-untracked -m "includes new files"

# Stash everything including .gitignore'd files (rarely needed)
git stash push -a -m "includes everything"

The -u flag is the one you want when you've started a new file and want to stash the whole working state including that file.

Stashing Specific Files or Hunks

You don't have to stash the entire working tree. You can stash specific files:

# Stash only specific paths
git stash push -m "just the payment changes" -- src/payment/ tests/payment/

# Stash specific hunks interactively
git stash push -p -m "partial stash"
# Walks through each hunk and asks y/n for stashing

The -p (patch) mode on stash is underused. It's the equivalent of git add -p — you can stash only part of a file's changes, leaving the rest in the working tree. This is useful when you want to commit one part of your work-in-progress and stash the other.

Stash as a Safety Net Before Risky Operations

Before any operation that could lose work:

# Always stash before a risky operation
git stash push -m "safety: before rebase onto main $(date '+%Y-%m-%d %H:%M')"
git rebase origin/main
# If it goes wrong:
git rebase --abort
git stash pop

This is a habit worth automating in a shell alias:

alias gsafe='git stash push -m "safety: $(date +%Y-%m-%d-%H%M)"'

Creating a Branch From a Stash

If you've been working on something in a stash that grew into something worth a proper branch:

# Create a new branch starting from the commit where you stashed,
# apply the stash on top, and drop it from the stack
git stash branch feature/new-thing stash@{1}

This is cleaner than manually applying the stash to a new branch because it handles the case where your stash was made from a now-diverged commit. The new branch starts from the right place.

Cleaning Up Old Stashes

Stashes accumulate. Run git stash list periodically and clean up ones you no longer need:

# Drop a specific stash
git stash drop stash@{2}

# Drop all stashes (careful — no undo for this)
git stash clear

Before dropping, inspect:

git stash show -p stash@{2}   # shows the full diff

The Limits of Stash

Stash is not a substitute for commits. Stashes don't have a commit message with context, they're not pushed to the remote (they live locally), and they're not part of your branch history. If your laptop dies, your stashes are gone.

If work-in-progress is significant enough that losing it would be painful, commit it (even as a WIP commit) and push. A WIP commit on a remote branch is recoverable. A stash on a dead laptop is not.

Use stash for short-duration parking — an hour, a day, a few days at most. For longer-running parked work, a WIP commit on a draft branch is the right tool.

Scale Your Backend - Need an Experienced Backend Developer?

We provide backend engineers who join your team as contractors to help build, improve, and scale your backend systems.

We focus on clean backend design, clear documentation, and systems that remain reliable as products grow. Our goal is to strengthen your team and deliver backend systems that are easy to operate and maintain.

We work from our own development environments and support teams across US, EU, and APAC timezones. Our workflow emphasizes documentation and asynchronous collaboration to keep development efficient and focused.

  • Production Backend Experience. Experience building and maintaining backend systems, APIs, and databases used in production.
  • Scalable Architecture. Design backend systems that stay reliable as your product and traffic grow.
  • Contractor Friendly. Flexible engagement for short projects, long-term support, or extra help during releases.
  • Focus on Backend Reliability. Improve API performance, database stability, and overall backend reliability.
  • Documentation-Driven Development. Development guided by clear documentation so teams stay aligned and work efficiently.
  • Domain-Driven Design. Design backend systems around real business processes and product needs.

Tell us about your project

Our offices

  • Copenhagen
    1 Carlsberg Gate
    1260, København, Denmark
  • Magelang
    12 Jalan Bligo
    56485, Magelang, Indonesia

More articles

Disagreeing With a Technical Decision Without Burning Bridges

Technical disagreements are inevitable in engineering teams. How they are handled determines whether the team's technical quality improves over time or whether decisions get made by whoever argues longest.

Read more

When Staging Access Requires Manager Approval

Ever waited hours just to test a feature on staging? When every access request has to go through a manager, productivity takes a hit.

Read more

Writing SQL That Still Makes Sense Six Months Later

SQL is easy to write fast and hard to read later — deliberate formatting, naming, and structure choices made at authoring time are the only thing that prevents your queries from becoming unmaintainable.

Read more

Why Barcelona Tech Startups Are Structuring Backend Work Around Contractors, Not Full-Time Hires

Some Barcelona startups have stopped treating every backend need as a headcount decision. The way they're structured explains why they keep shipping.

Read more