Git stash lets you temporarily set aside local changes without committing them. It is useful when you are halfway through one task and suddenly need to switch branches to fix something urgent.
Instead of creating a messy âwork in progressâ commit, you can stash the changes, do the urgent task, and then restore your original work later.
Tip: Stash is great for short-term interruptions. For longer work, a real branch and commit are usually safer.
Suppose you modified app.js and README.md but are not ready to commit.
Check the status:
git statusNow stash the tracked changes:
git stashGit saves the current state and reverts your working directory to match the last commit.
You can confirm with:
git statusThe working tree should now be clean.
To see saved stashes:
git stash listExample output:
stash@{0}: WIP on feature/login: a1b2c3d Add login page
stash@{1}: WIP on main: d4e5f6g Update READMEEach stash has an identifier like stash@{0}.
applyUse git stash apply when you want to restore a stash but keep it in the stash list.
git stash apply stash@{0}This is useful if you want to test the restored changes before deciding whether to remove the stash entry.
If you omit the name, Git applies the latest stash:
git stash applypopUse git stash pop when you want to restore a stash and remove it from the stash list in one step.
git stash popThis is the most common restore command.
apply vs popapply: restore but keep the stash savedpop: restore and delete the stash entry if successfulDefault stash messages are not always easy to remember. You can create a named stash:
git stash push -m "half-finished navbar styling"List it later:
git stash listNamed stashes are much easier to identify when you have several saved states.
By default, git stash saves changes to tracked files only. If you also want to include untracked files, use -u.
git stash push -u -m "save new config files too"This is helpful when you created new files but are not ready to commit them yet.
Note: Untracked files are files Git sees but is not yet tracking. Ignored files are a separate category and are not included unless you use additional options.
To delete one stash entry:
git stash drop stash@{0}To remove all stash entries:
git stash clearBe careful with clear because it removes everything from the stash list.
Imagine you are on feature/docs editing tutorial content when a production issue appears.
git status
git stash push -m "draft updates for Git basics"
git switch main
git switch -c hotfix/header-bug
# fix the issue
git add .
git commit -m "Fix broken header in production"
git switch feature/docs
git stash popThis lets you pause one task, fix another, and return without creating a confusing temporary commit.
Applying a stash can sometimes create conflicts, especially if the branch changed since the stash was created.
If that happens:
git statusgit addA stash is not magic. It still depends on how different the files became over time.
Stash is not ideal for everything.
Avoid relying on stash when:
In those cases, a normal branch and commit are usually better.
Git stash is a temporary shelf for unfinished work. Use stash to save changes quickly, list to inspect saved entries, apply or pop to restore them, and drop or clear to clean them up. Use -u for untracked files and -m for a helpful message.
For quick interruptions, stash is excellent. For meaningful milestones, commit to a branch instead.
Scenario: You are halfway through editing app.js and README.md, and an urgent bug forces you to switch tasks immediately.
Question: Which Git feature from this lesson is designed for that short-term interruption without making a work-in-progress commit?
<MCQExercise exercise={{ id: 'git-stash-q1', title: 'Exercise 1: Pausing work quickly', description: 'Choose the Git feature intended for temporarily shelving unfinished local changes.', options: [ { id: 'a', text: 'git tag' }, { id: 'b', text: 'git stash' }, { id: 'c', text: 'git revert' }, { id: 'd', text: 'git cherry-pick' }, ], correctId: 'b', explanation: 'The tutorial positioned stash as a short-term shelf for unfinished local changes. It is a clean way to pause one task, switch context, and later restore the saved work.', wrongExplanations: { a: 'Tags mark commits in history, not temporary uncommitted working changes.', c: 'Revert creates a new commit that undoes an earlier commit. It does not shelve in-progress edits.', d: 'Cherry-pick copies an existing commit to another branch, which is unrelated to pausing uncommitted work.', }, }} />
Scenario: Your unfinished work includes brand-new config files that are still untracked, and you want a descriptive stash entry.
Question: Which command best matches the tutorial?
<MCQExercise
exercise={{
id: 'git-stash-q2',
title: 'Exercise 2: Saving untracked files too',
description: 'Choose the stash command that includes untracked files and adds a helpful message.',
options: [
{ id: 'a', text: 'git stash clear -m "save config"' },
{ id: 'b', text: 'git stash apply -u "save config"' },
{ id: 'c', text: 'git stash drop -u -m "save config"' },
{ id: 'd', text: 'git stash push -u -m "save config"' },
],
correctId: 'd',
explanation: 'The lesson showed git stash push -u -m "..." for exactly this case. -u includes untracked files, and -m adds a meaningful label that is easier to recognize later in git stash list.',
wrongExplanations: {
a: 'clear removes stashes; it does not create a new one.',
b: 'apply restores an existing stash and does not create a named stash entry.',
c: 'drop deletes an existing stash entry rather than saving your current work.',
},
}}
/>
Scenario: You want to restore a stash to test something, but you do not want the stash entry removed yet.
Question: Which command should you prefer?
<MCQExercise
exercise={{
id: 'git-stash-q3',
title: 'Exercise 3: Keeping the stash after restore',
description: 'Pick the restore command that leaves the stash entry in the list.',
options: [
{ id: 'a', text: 'git stash apply' },
{ id: 'b', text: 'git stash pop' },
{ id: 'c', text: 'git stash clear' },
{ id: 'd', text: 'git stash branch' },
],
correctId: 'a',
explanation: 'The tutorial contrasted apply with pop: apply restores the changes but keeps the stash entry saved. That is useful when you want to verify or reuse the stash before deleting it.',
wrongExplanations: {
b: 'pop usually restores and removes the stash entry, which is the opposite of the goal here.',
c: 'clear deletes all stash entries and would destroy the saved work.',
d: 'The lesson focused on apply versus pop for restore behavior, and branch creation is not the simplest answer to this question.',
},
}}
/>
No, and this surprises people regularly. A plain git stash leaves new files sitting in your working directory, so switching branches carries them along and a "clean" stash turns out not to be. Use git stash -u (or --include-untracked) to include them, and git stash -a (--all) to include ignored files as well. Because -a sweeps up build output and node_modules, it is rarely what you want.
git stash list shows the entries with their references. git stash show stash@{0} gives a summary of changed files, and git stash show -p stash@{0} prints the full diff. You can also restore a single file from a stash without applying the whole thing: git checkout stash@{0} -- path/to/file. Naming stashes as you create them, git stash push -m "half-done search filter", makes the list readable a week later, which the default WIP on main messages do not.
Usually yes. A dropped stash is an unreachable commit, and git fsck --unreachable | grep commit lists candidates you can inspect with git show <sha>. Once you find it, git stash apply <sha> restores the contents. It works until Git garbage-collects, which is typically not for weeks. The wider lesson is that stashes are the least durable place to keep work. A throwaway commit on a scratch branch is recoverable through the reflog and cannot be dropped by a stray git stash clear.
Just switch branches and apply it. Stashes are not tied to the branch they were created on. git switch other-branch then git stash pop is a standard way to move work you started in the wrong place. Conflicts are possible if the branches have diverged in the same files, and git checkout --theirs/--ours plus normal conflict resolution applies. If you expect trouble, use apply rather than pop so the stash survives a failed attempt.
Whenever the work will outlive the next half hour. A stash is an unnamed, unordered pile that is easy to forget and easy to clear, and git stash list after a busy fortnight is nobody's friend. For anything you intend to return to, commit it on a branch, even as a scrappy "wip" commit you later amend or squash. Stash is at its best for exactly what it was designed for: parking a few minutes of work to pull, switch branch for a quick fix, or check something on a clean tree.
Undo almost anything in Git: restore files, reset soft, mixed and hard, revert on shared branches, clean untracked files and recover a bad reset with reflog.
Mark releases with Git tags: lightweight versus annotated, why push ignores tags, deleting them safely, tagging older commits and semantic-versioned releases.
Follow the GitHub pull request workflow end to end: fork versus clone, keeping a branch current, squash versus merge versus rebase, and reviewing well.