You’re working on something, haven’t committed yet, and need to switch to a different branch in Git. Maybe a bug came in that needs fixing on main, or you realized you’ve been working on the wrong branch. If your uncommitted changes don’t conflict with the target branch, Git lets you switch freely. But if there’s a conflict, you’ll get this error:
error: Your local changes to the following files would be overwritten by checkout:
src/app.py
Please commit your changes or stash them before you switch branches.
There are three ways to handle this. Which one you pick depends on whether you want to keep the changes temporarily, permanently, or just carry them over.
Method 1: git stash (Most Common)
Git stash saves your uncommitted changes to a temporary storage area, cleans your working directory, and lets you switch branches. When you come back, you pop the stash and your changes are restored.
git stash
git switch bugfix-branch
# ... do your work on the other branch ...
git switch - # switch back to previous branch
git stash pop
git switch - is a shortcut that switches to whatever branch you were on before — like cd - in the terminal.
Stash with a Message
If you stash often, add a description so you know what’s in each stash later:
git stash push -m "WIP: user authentication form"
Including Untracked Files
By default, git stash only saves tracked files that have been modified. New files that haven’t been added to Git yet (untracked files) are left behind. To include them:
git stash push -u -m "WIP: including new files"
The -u flag includes untracked files. This is one of those things you’ll forget once and then always remember after — you stash, switch branches, and realize your new file is still sitting there.
Managing Multiple Stashes
Stashes stack up. View them with:
git stash list
stash@{0}: On feature-branch: WIP: user authentication form
stash@{1}: WIP on main: abc1234 fix header
A few commands for managing them:
# Apply the latest stash and remove it from the stash list
git stash pop
# Apply the latest stash but keep it in the list (in case you need it again)
git stash apply
# Apply a specific stash
git stash apply stash@{1}
# Delete a specific stash
git stash drop stash@{1}
# Delete all stashes
git stash clear
The difference between pop and apply: pop removes the stash after applying it. apply keeps it around. Use apply if you’re not sure the changes will work cleanly on the new branch — you can always drop it later.
Method 2: Switch Directly (When There’s No Conflict)
If the files you’ve modified don’t exist on the target branch (or exist but haven’t changed), Git will carry your uncommitted changes over when you switch:
git switch other-branch
Your changes stay in the working directory — they just come along for the ride. No stashing needed. Check git status on the new branch and you’ll see them right there.
This works more often than you’d think. The error only happens when the same file was changed on both sides. If you’re worried, try the switch — if there’s a conflict, Git won’t do anything and will tell you. Nothing gets lost.
Method 3: WIP Commit
If you want the changes saved in Git history (not just stashed temporarily), commit them with a “work in progress” message:
git add .
git commit -m "WIP: save progress before switching"
git switch other-branch
When you come back, you can keep working and amend the commit later, or squash it into your next real commit. If you use interactive rebase, check out How to Combine All Commits into One with GitLens Interactive Rebase in VSCode for cleaning up WIP commits before merging.
To undo the WIP commit but keep the changes staged:
git reset --soft HEAD~1
This moves the branch pointer back one commit but leaves all your files exactly as they were. You’re back to having uncommitted changes, ready to keep working.
Moving Changes to a New Branch
Sometimes you realize you’ve been coding on the wrong branch — you want your uncommitted changes on a brand new branch instead. You don’t need to stash for this:
git switch -c correct-branch
The -c flag creates the new branch and switches to it, carrying your uncommitted changes along. This is the same as the old git checkout -b syntax. For more on this pattern, see Safety Moving Uncommitted Changes to A New Branch in Git.
git switch vs git checkout
All the examples here use git switch, which was introduced in Git 2.23. It does the same thing as git checkout for branch switching, but it’s clearer in intent — checkout does too many things (switching branches, restoring files, detaching HEAD), while switch only switches branches.
| Old Command | New Command |
|---|---|
git checkout branch-name |
git switch branch-name |
git checkout -b new-branch |
git switch -c new-branch |
git checkout - |
git switch - |
Both still work. If your Git version is older than 2.23, you can upgrade Git on Ubuntu to get git switch. Or just keep using checkout — it’s not going anywhere.
Which Method Should You Use?
| Situation | Best Option |
|---|---|
| Quick branch switch, expecting to come right back | git stash + git stash pop |
| No conflicting files | Just git switch branch directly |
| Changes need to be saved in history | WIP commit |
| Started work on the wrong branch | git switch -c correct-branch |
| Need to stash but also have new files | git stash push -u |
Conclusion
For most cases, git stash is what you want — it’s quick, reversible, and keeps your commit history clean. Direct switching works when there’s no conflict. And a WIP commit is fine when you want things saved in Git properly.
If you run into merge conflicts when switching branches, How to Merge Branches in Git Without Auto-Resolving Conflicts covers how to handle those manually.


