Articles

Git Stash Explained: Shelve Changes Without Committing

Git stash saves uncommitted work to a hidden stack so you can switch branches cleanly. How stash, pop, apply, and stash branches actually work.

The Lycoris Team The Lycoris Team · · 4 min read
Git version control branching visualization

git stash takes your uncommitted changes — staged and unstaged — and saves them to a hidden stack, restoring your working directory to match the last commit. It’s the tool for the moment you’re mid-edit, need to switch branches or pull a fix, and don’t want to make a throwaway commit just to clear your working tree.

The basic workflow

git stash          # save changes, clean working directory
git checkout main  # switch branches freely
git checkout feature-branch
git stash pop       # reapply the stash and remove it from the stack

git stash (short for git stash push) bundles your modified tracked files into a commit-like object and resets the working directory to HEAD. git stash pop reapplies the most recent stash and removes it from the stack; git stash apply reapplies it but leaves it on the stack, useful if you want to apply the same stash to more than one branch.

By default, git stash only captures changes to tracked files. Untracked and ignored files are left alone unless you ask for them explicitly:

git stash -u   # include untracked files
git stash -a   # include untracked and ignored files

This trips people up constantly: you stash, switch branches, come back, and the new files you created are still sitting there because they were never tracked in the first place — which is usually fine, but can be confusing if you expected a clean slate.

Managing multiple stashes

Stashes stack — you can stash more than once without popping in between, and each one gets an index:

git stash list
# stash@{0}: WIP on feature-branch: a1b2c3d Add validation
# stash@{1}: WIP on main: e4f5g6h Fix typo

git stash show stash@{1}       # summary of what changed
git stash show -p stash@{1}    # full diff
git stash apply stash@{1}      # apply a specific stash, not just the latest
git stash drop stash@{1}       # discard a stash without applying it
git stash clear                # discard all stashes

Give a stash a name if you’ll have more than one in flight, since “WIP on feature-branch” descriptions all start to look the same after a few days:

git stash push -m "half-finished pagination logic"

Stashing part of your changes

git stash push accepts pathspecs, so you can stash only some files and leave the rest staged or in the working directory:

git stash push -- src/api/users.ts

For finer control — stashing individual hunks within a file — use git stash -p, which walks through each hunk and asks whether to include it, the same interactive prompt used by git add -p.

Turning a stash into a branch

If a stash conflicts badly with the branch you’re trying to apply it to, git stash branch creates a new branch from the commit the stash was taken on, checks it out, and applies the stash there — sidestepping the conflict entirely:

git stash branch new-feature stash@{0}

This is the fix for the common failure mode where you stash on one commit, do a bunch of unrelated work, then try to pop the stash back onto a branch that’s since diverged and no longer applies cleanly.

How it compares to alternatives

git stashcommit + amendworktree
SpeedInstantRequires a message, still visible in logRequires a new checkout
Pollutes historyNoYes, until squashedNo
Works across branchesYesYes, via cherry-pickN/A — separate directory entirely
Good for long-lived parallel workNoNoYes

For genuinely long-running parallel work — not just “I need to switch branches for five minutes” — a git worktree is usually the better tool, since it gives you a second working directory instead of a single directory juggling saved states. Stash is for short interruptions; worktrees are for running two branches side by side.

Where stashes live and how they’re lost

Stashes are stored as commit objects referenced by refs/stash, which means they’re subject to garbage collection like any unreferenced commit once dropped — git stash drop doesn’t shred the data instantly, but don’t rely on recovering it either. If you’ve popped or dropped a stash by mistake, git fsck --unreachable can sometimes surface the dangling commit before garbage collection sweeps it away, but this isn’t a substitute for actually committing work you care about. Stash is explicitly meant for transient, disposable state, not long-term storage — if something needs to survive a git stash clear or a machine wipe, commit it, even to a scratch branch. That distinction matters more once you’re doing a rebase or a cherry-pick across branches, where an uncommitted stash can quietly get left behind on the wrong checkout.

The takeaway

git stash is a fast, local escape hatch for uncommitted work you’re not ready to commit but don’t want to lose. Use plain stash/pop for the common case of switching branches and coming right back, reach for -u when untracked files matter, name your stashes once you have more than one, and use stash branch when a stash no longer applies cleanly to where you’re trying to put it. For anything that needs to survive longer than a few minutes or move across more than one branch, commit it instead.

The Lycoris Team The Lycoris Team · · 4 min read

What Is Git Reflog? Recovering Lost Commits

Git reflog records every place HEAD and branch tips have pointed, letting you recover commits that look lost after a reset, rebase, or deleted branch.

#Git #Developer Tools #Version Control
The Lycoris Team The Lycoris Team · · 5 min read

What Are Conventional Commits? A Commit Convention

Conventional Commits structures commit messages as type(scope): description so tools can auto-generate changelogs and version bumps from git history.

#Git #Developer Tools #Version Control