Technology git stash

Learn with diagrams, code, systems and practical examples.

</>

Git command reference · working state

git stash: save the right temporary state before you switch context

Stash temporarily records selected working-tree and index changes so you can return to a clean state without creating a normal project commit. The important skill is deciding exactly which state should be saved, what should remain visible, and how you will restore it safely.

Think before running it

You changed a tracked file and created a new untracked file. If you run plain git stash push, should both disappear from git status?

Reveal the state change

No. The tracked changes are stashed, but the untracked file is normally left in the working tree. If the new file belongs to the same temporary work, use --include-untracked and verify the resulting state.

Safety principle: A stash is safest when you can name exactly which repository state it captures and when you keep the entry until the restored work has been inspected and tested. Temporary convenience should not become invisible data loss.

01 · Inspect

Separate staged, unstaged, untracked, and ignored state.

  • Run git status and identify staged, unstaged, untracked, and ignored files separately.
  • Decide whether untracked files belong to the temporary work; do not use -u or -a automatically.
  • If only some hunks should be set aside, use --patch instead of stashing the entire file.
  • Give meaningful stashes a message so stash@{n} entries can be distinguished later.
  • If the work must survive beyond a short context switch, prefer a real commit/branch and remote backup.

02 · Predict

Choose an option because of the boundary you want to preserve.

-u, --include-untracked

Include untracked files in the stash in addition to the normally stashed tracked changes.

When new untracked files are part of the work you must set aside before changing context.
-a, --all

Include untracked and ignored files as well as tracked changes.

Only when ignored generated/local files are intentionally part of the temporary snapshot; inspect carefully because this captures more state than most stashes need.
-S, --staged

Stash only changes currently staged in the index.

When staged work is one coherent unit you want to set aside while keeping unrelated working-tree edits visible.
-p, --patch

Interactively choose hunks to stash.

When one file contains both work you want to set aside and work you want to keep in the working tree.
--keep-index

Keep changes already staged in the index while stashing other selected changes.

When the staged snapshot is ready for testing/commit and you want to temporarily hide unrelated unstaged work.
--index

When applying or popping a stash, also try to reinstate the staged-versus-unstaged index state recorded by the stash.

When preserving the original staging boundary matters and you understand that conflicts can prevent exact index restoration.

03 · Run

Practice on realistic context switches.

Beginner: set aside tracked edits before switching tasks

You are halfway through a tracked-file change when an urgent fix arrives. You need a clean working tree but do not want a temporary project commit.

git status
git stash push -m "wip: profile form"
git status
git stash list

Inspect first. The stash records the selected tracked changes and returns those paths toward the HEAD state so you can switch context. The message makes the temporary snapshot easier to identify later.

Expected: Saved working directory and index state … followed by a clean or simpler git status.

Practical: include a new untracked file that belongs to the work

Your change includes edits to tracked files plus a new untracked component file. A normal stash would leave the untracked file behind.

git status
git stash push -u -m "wip: search panel"
git stash show --stat stash@{0}

--include-untracked captures the new file as part of the temporary snapshot. Inspecting the stash afterward helps verify that the intended work—not unrelated files—was saved.

Advanced: keep staged work visible while hiding unrelated edits

You staged a small tested fix, but the same working tree also contains unrelated experiments that make a focused test noisy.

git status
git stash push --keep-index -m "hide unrelated experiments"
# test or commit the staged fix
git stash apply stash@{0}

--keep-index leaves the staged snapshot in place while stashing other selected work. Apply restores the stash but deliberately keeps the stash entry, giving you a recovery checkpoint until you verify the restored state.

Recovery: branch from the stash’s original base

A stash created days ago conflicts badly with the branch as it exists today. You want to continue the old work from the commit where it originally made sense.

git stash list
git stash branch recover/profile stash@{1}

git stash branch creates a new branch starting from the commit that was HEAD when the stash was created, then applies the stashed work there. This often avoids conflicts caused only by later changes on the current branch.

04 · Verify & recover

When a stash does not restore cleanly, preserve the evidence first

A stash can conflict when the target branch changed after the temporary snapshot was created. The goal is to preserve the stash entry and reconstruct the intended working state deliberately.

  1. Inspect the target before applying

    Confirm the branch is the intended destination and understand its current changes.

    git status
    git log --oneline --decorate -n 8
  2. Inspect the stash itself

    Review the stash list and patch/stat before applying an older or ambiguously named entry.

    git stash list
    git stash show -p stash@{0}
  3. Prefer apply when uncertainty is high

    Apply while keeping the stash entry so you retain an easy retry/reference point.

    git stash apply stash@{0}
  4. Resolve conflicts as a normal integration problem

    Use git status, reconcile the intended changes with the current branch, then test the result. A conflicted pop keeps the stash entry; verify that with git stash list.

  5. Use stash branch when the old base matters

    If later branch changes are the main source of conflict, recreate a branch from the stash’s original base and apply there.

    git stash branch recover/stashed-work stash@{0}
  6. Drop only after verification

    Remove the stash entry only after the restored work is confirmed and safely represented elsewhere.

    git stash drop stash@{0}

Apply vs pop

Keep the stash until the restored work is proven.

git stash apply applies the snapshot and keeps the stash entry. git stash pop removes the entry only when application succeeds. If pop conflicts, the stash entry remains; inspect git stash list, resolve the working state, test it, and drop the entry only when recovery is complete.

Mistakes worth rehearsing

Temporary state becomes dangerous when it is invisible.

Assuming untracked files are included automatically

The normal stash operation focuses on tracked state. New untracked files can remain in the working tree and may block a checkout or be forgotten.

Recovery: Run git status before stashing. Use --include-untracked only when those new files belong to the temporary work, then inspect git status again.

Using pop before you know the stash applies cleanly

pop combines application with removal when application succeeds. If you are unsure about the target branch or want an easy retry point, deleting the stash immediately is unnecessary risk.

Recovery: Prefer git stash apply <stash> first, inspect/test the result, and drop the stash explicitly only after you are confident the recovery is complete.

Treating a conflicted pop as if the stash must be gone

When git stash pop encounters conflicts, Git does not remove the stash entry automatically. The conflict must be resolved and the stash can be dropped later when no longer needed.

Recovery: Read git status, resolve the conflicted paths, test the result, then inspect git stash list before deciding whether to drop the entry.

Using stash as long-term backup

Stashes live inside the repository and are designed as temporary working-state snapshots. They are easier to forget, drop, or lose than normal commits shared to a remote.

Recovery: For work that matters beyond a short context switch, create a real commit on a branch and push it to an appropriate remote according to the project workflow.

Running clear because the list looks untidy

git stash clear removes all stash entries. Recovery after dropping or clearing entries is not the normal supported workflow and should not be treated as a dependable safety net.

Recovery: Inspect each entry with git stash list/show and drop only the entries you have verified are disposable.

Guided practice

You have one staged fix that you want to keep visible for a focused test, plus unrelated unstaged experiments that should disappear temporarily. What should you inspect and run?

Hint

The staging boundary is part of the desired state. Choose an option whose name says the index should remain.

git status
git stash push --keep-index -m "hide experiments for focused test"
git status
# run the focused test
git stash apply stash@{0}

--keep-index leaves the staged snapshot available while setting aside the other selected working changes. Using apply instead of pop keeps the stash entry until the restored result has been inspected.

Independent practice

In a disposable repository, create one staged edit, one unstaged edit, and one untracked file. Predict the result of plain stash, --include-untracked, --staged, --keep-index, and --patch before running each case. Then move the branch forward, create a deliberate stash conflict, practice apply plus manual resolution, and finally repeat with git stash branch to compare the recovery experience.

FAQs

What is the difference between git stash apply and git stash pop?

Both try to apply a stash. apply keeps the stash entry; pop removes it only after a successful application. Use apply when you want a safer verification checkpoint before deleting the temporary snapshot.

Does git stash include untracked files?

Not by default. Use -u/--include-untracked when untracked files belong to the work you are setting aside. Use -a/--all only when ignored files should also be captured deliberately.

Can I stash only staged changes?

Yes. git stash push --staged records the changes currently staged in the index. This is useful when the staged set is a distinct unit from other working-tree edits.

Can I stash only part of a file?

Yes. git stash push -p/--patch lets you select hunks interactively, so you can set aside only part of the current diff.

What should I do if an old stash conflicts on my current branch?

First inspect the stash and current state. If the conflict comes from the branch moving far beyond the stash’s original base, git stash branch <new-branch> <stash> can recreate a branch from the original base and apply the work there.