Skip to content

Temporarily Parking Changes with git stash

Suppose you are editing the Login feature on feature-login. The work is not ready for a meaningful commit, but an urgent fix requires you to switch to main.

Git may allow the dirty changes to travel to main, or it may refuse the switch if the target snapshot would overwrite them. Neither outcome means you should create a vague, incomplete commit merely to change branches.

git stash provides temporary parking for this situation.

A normal branch switch updates HEAD, the Index, and tracked Working Tree files to represent the target branch. Local changes complicate this operation:

  • They may remain safely and follow the switch.
  • They may be committed accidentally on the wrong branch later.
  • Git may refuse the switch to protect them from being overwritten.

A Stash entry records selected unfinished changes, then normally restores the Working Tree and Index to a clean state based on HEAD.

Dirty feature-login
│
│ git stash push
▼
Clean feature-login + saved stash entry
│
│ git switch main
▼
Work safely on main
│
│ return, then apply the stash
▼
Unfinished Login changes are back

First inspect the repository:

Terminal window
git status
git diff
git diff --staged

Then save the tracked staged and unstaged changes with a useful message:

Terminal window
git stash push -m "wip: login validation"
git stash push
Creates a new Stash entry from the selected local changes.
-m "wip: login validation"
Adds a message so the entry can be recognized later.

push is preferred to a bare git stash because it makes the intended operation explicit and supports useful options.

After a successful push, run:

Terminal window
git status

The tracked Working Tree and Index should normally be clean. The unfinished work has not become part of the current branch’s normal commit history.

By default, git stash push saves:

  • Modifications to tracked files in the Working Tree.
  • Changes already staged in the Index.

It does not normally include untracked or ignored files.

File state Included by default?
Tracked and unstaged Yes
Tracked and staged Yes
Untracked No
Ignored No

If the Login work includes a new untracked file, use:

Terminal window
git stash push -u -m "wip: login validation"

-u is the short form of --include-untracked. It includes untracked files in the Stash entry and removes them temporarily from the Working Tree.

Ignored files are still excluded. Options that include ignored files exist, but they are deliberately outside this beginner workflow because generated dependencies and secret files may be large or inappropriate to stash.

Terminal window
git stash list

Example:

stash@{0}: On feature-login: wip: login validation
stash@{1}: On main: wip: update authentication logs
  • stash@{0} is the newest entry.
  • stash@{1} is the next older entry.
  • The position can change when new entries are added or existing ones are removed.
  • The branch name describes where the Stash was created; it does not prevent applying it elsewhere.

Show a changed-file summary:

Terminal window
git stash show --stat stash@{0}

Show the complete patch:

Terminal window
git stash show -p stash@{0}
show
Displays a selected Stash entry.
--stat
Displays a changed-file summary.
-p
Displays the line-by-line patch.
stash@{0}
Selects the newest Stash entry explicitly.

Inspecting the entry prevents restoring the wrong work when several Stashes exist.

Terminal window
git stash apply stash@{0}

apply tries to restore the selected changes but keeps the Stash entry in the list. This is the safer default while learning because the saved entry remains available until you verify the result.

After applying:

Terminal window
git status
git diff
git diff --staged

Review the resulting Working Tree and Index rather than assuming every state was restored exactly as expected.

Terminal window
git stash pop stash@{0}

pop attempts to apply the entry and, if the application succeeds, removes that entry from the Stash list.

apply
Restore the changes and keep the Stash entry.
pop
Restore the changes and remove the entry after a successful application.

When conflicts occur, Git normally keeps the entry so it is not silently lost. You must resolve the Working Tree conflicts and then decide when the saved entry is no longer needed.

Prefer apply, verify the files, and delete the entry deliberately while learning. pop is convenient when you understand the consequences.

A Stash records changes relative to the project state where it was created. If the target branch has since changed the same lines, Git may not be able to combine them automatically.

Stash changes auth.js line 20
Target branch also changes auth.js line 20
↓
conflict may occur

Applying a Stash is not simply copying files back. Git attempts to reapply changes in a new context, similar to a small merge operation.

If a conflict occurs:

  1. Run git status.
  2. Open every conflicted file.
  3. Resolve the conflict deliberately.
  4. Stage the resolved files when appropriate.
  5. Verify and test the result.
  6. Delete the Stash entry only when the work is safely recovered.

Detailed conflict resolution is covered with merging later.

After a successful apply and verification:

Terminal window
git stash drop stash@{0}

drop deletes the selected Stash entry without applying it. Always specify and inspect the intended entry when several entries exist.

Terminal window
git status
git diff
git diff --staged
Terminal window
git stash push -u -m "wip: login validation"
git status
Terminal window
git switch main

Make and commit the coherent urgent fix, then return:

Terminal window
git switch feature-login
Terminal window
git stash list
git stash show -p stash@{0}
Terminal window
git stash apply stash@{0}
git status

After reviewing and testing the restored work:

Terminal window
git stash drop stash@{0}

Use -u when the intended work contains untracked files, and inspect them first.

Stash entries are local and can be dropped or expired. Convert valuable work into clear commits when it is ready.

Using pop without knowing which entry is newest

Section titled “Using pop without knowing which entry is newest”

Run git stash list and specify the intended stash@{n}.

Applying on an unrelated branch without inspection

Section titled “Applying on an unrelated branch without inspection”

The changes can conflict or create an incorrect combination. Inspect with git stash show -p first.

Confirm the restored files and tests before deleting the saved entry.

Goal Command
Save tracked changes with a message git stash push -m "wip: login validation"
Also include untracked files git stash push -u -m "wip: login validation"
List entries git stash list
Inspect the complete patch git stash show -p stash@{0}
Restore and keep the entry git stash apply stash@{0}
Restore and remove after success git stash pop stash@{0}
Delete a selected entry git stash drop stash@{0}

git stash temporarily records selected unfinished changes so the Working Tree and Index can become clean. Inspect the entry, restore it deliberately, expect possible conflicts if the target changed, and never treat Stash as a permanent backup or normal project history.