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.
The problem Stash solves
Section titled “The problem Stash solves”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 backCreate a named Stash entry
Section titled “Create a named Stash entry”First inspect the repository:
git statusgit diffgit diff --stagedThen save the tracked staged and unstaged changes with a useful message:
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:
git statusThe tracked Working Tree and Index should normally be clean. The unfinished work has not become part of the current branch’s normal commit history.
What is included by default?
Section titled “What is included by default?”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 |
Include untracked files
Section titled “Include untracked files”If the Login work includes a new untracked file, use:
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.
List saved entries
Section titled “List saved entries”git stash listExample:
stash@{0}: On feature-login: wip: login validationstash@{1}: On main: wip: update authentication logsstash@{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.
Inspect before restoring
Section titled “Inspect before restoring”Show a changed-file summary:
git stash show --stat stash@{0}Show the complete patch:
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.
Restore with apply
Section titled “Restore with apply”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:
git statusgit diffgit diff --stagedReview the resulting Working Tree and Index rather than assuming every state was restored exactly as expected.
Restore with pop
Section titled “Restore with pop”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.popis convenient when you understand the consequences.
Why can applying a Stash conflict?
Section titled “Why can applying a Stash conflict?”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 20Target branch also changes auth.js line 20 ↓ conflict may occurApplying 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:
- Run
git status. - Open every conflicted file.
- Resolve the conflict deliberately.
- Stage the resolved files when appropriate.
- Verify and test the result.
- Delete the Stash entry only when the work is safely recovered.
Detailed conflict resolution is covered with merging later.
Delete an entry deliberately
Section titled “Delete an entry deliberately”After a successful apply and verification:
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.
Complete practical workflow
Section titled “Complete practical workflow”1. Inspect unfinished Login work
Section titled “1. Inspect unfinished Login work”git statusgit diffgit diff --staged2. Park tracked and untracked work
Section titled “2. Park tracked and untracked work”git stash push -u -m "wip: login validation"git status3. Switch and complete the urgent fix
Section titled “3. Switch and complete the urgent fix”git switch mainMake and commit the coherent urgent fix, then return:
git switch feature-login4. Find and inspect the saved work
Section titled “4. Find and inspect the saved work”git stash listgit stash show -p stash@{0}5. Apply without deleting the safety copy
Section titled “5. Apply without deleting the safety copy”git stash apply stash@{0}git status6. Verify, then remove the entry
Section titled “6. Verify, then remove the entry”After reviewing and testing the restored work:
git stash drop stash@{0}Common mistakes
Section titled “Common mistakes”Assuming untracked files are included
Section titled “Assuming untracked files are included”Use -u when the intended work contains untracked files, and inspect them
first.
Treating Stash as permanent history
Section titled “Treating Stash as permanent history”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.
Dropping before verification
Section titled “Dropping before verification”Confirm the restored files and tests before deleting the saved entry.
Command summary
Section titled “Command summary”| 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} |
Key takeaway
Section titled “Key takeaway”
git stashtemporarily 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.