Stashing Untracked Files
The single most common stash bug report is "my new file followed me to another branch." The reason is simple: by default, git stash does not include untracked files. If Git has never seen the file before, it stays in place when you stash. This page covers how to include untracked (and ignored) files, and when to use a WIP commit instead.
The default behaviour
What stash sees and ignores
echo "// new" > src/feature.js echo "// edited" >> src/existing.js git status # Changes not staged for commit: # modified: src/existing.js # Untracked files: # src/feature.js git stash # Saved working directory and index state WIP on main: ... git status # Untracked files: # src/feature.js
Only the modification to existing.js was stashed. feature.js is still sitting there, untracked. Switch branches now and it will appear to "follow" you — but really it's not following anything; it's in the working directory and Git just hasn't been told what to do with it.
Including untracked files: -u
The fix
git stash push -u -m "feature + edits" # or --include-untracked git status # nothing to commit, working tree clean
-uadds untracked files (those not in.gitignore).It still respects your gitignore — ignored files are not stashed.
On restore, the untracked files reappear as untracked, not staged.
Including ignored files: -a
The much rarer flag
git stash push -a -m "include build artifacts too" # or --all
Flag comparison
Flag | Tracked + modified | Staged | Untracked | Ignored |
|---|---|---|---|---|
(none) | Yes | Yes | No | No |
| Yes | Yes | Yes | No |
| Yes | Yes | Yes | Yes |
The classic mistake
Untracked file 'follows' a branch switch
# On feature/login echo "// scratch" > src/scratch.js # untracked git stash git switch main ls src/ # scratch.js # still here # If you commit on main now and push, scratch.js could leak. # Worse: if it conflicts with a real file on another branch, # you get a confusing checkout error.
Defensive habit: check before stashing
A one-second habit
git status # look at the Untracked section # If anything important is there, use -u git stash push -u -m "..."
When ignored files actually matter
A scratch file you put in an ignored directory and forgot about —
-ais the only way to stash it short of un-ignoring.You're reproducing a bug that depends on a generated artifact you can't regenerate quickly.
You're moving between machines via patch files and want byte-for-byte fidelity (in which case, prefer
git format-patchover stash).
Most days, the answer is: don't stash ignored files. They're ignored for a reason — they're reproducible, large, or sensitive.
The better alternative for new files: a WIP commit
When you have lots of new files, branches beat stash
git switch -c wip/login-form git add -A git commit -m "WIP: login form scaffolding" # Later, when ready: git switch feature/login git cherry-pick wip/login-form # or rebase # ...and git branch -D wip/login-form when done
Why prefer this for new files? Because:
A commit is reflog-protected for ~90 days; a stash for ~30.
A branch is pushable. You can back it up to the remote.
You can reference it by name forever — no fragile
stash@{2}index.You can rebase, cherry-pick, or PR it directly.
Real-world recipe: catching the "follows me" bug
The whole flow
# 1. Always status first git status # Untracked files: # src/new-thing.js # 2. Decide: stash with -u, OR commit on a WIP branch git stash push -u -m "WIP including new-thing.js" # 3. Move freely git switch main git pull # 4. Come back and restore — untracked file returns as untracked git switch - git stash pop
Interaction with .gitignore
git stash -u honours .gitignore exactly as the rest of Git does. If you keep your .gitignore clean, -u is almost always safe to use. If your .gitignore is sloppy, you'll sometimes accidentally stash files you didn't mean to — another argument for keeping your ignore rules tidy.