Git Developer Guide
error: Your local changes to the following files would be overwritten by checkout
What Git is refusing to do
You edited a file on main, did not commit it, and tried to switch to another branch where that same file is different. Git stops rather than lose the edit. git switch and git checkout print the identical message:
$ git status --short
M config.json
$ git switch feature/timeouts
error: Your local changes to the following files would be overwritten by checkout:
config.json
Please commit your changes or stash them before you switch branches.
Aborting
Nothing has changed. You are still on main and your edit is still in the file. The outputs on this page come from a throwaway repository on Git 2.50, where main has "timeout": 30 and feature/timeouts raised it to 60.
Why it happens, and why it sometimes does not
Switching branches rewrites every file that differs between the commit you are on and the commit you are going to. A file that is the same in both is left alone, uncommitted edits and all. So the error only fires for files that are both modified in your working tree and different on the target branch. That is why a dirty tree often switches fine:
$ git status --short
M README.md
$ git switch feature/timeouts
Switched to branch 'feature/timeouts'
M README.md
README.md is identical on both branches, so the edit rides along and Git lists it as M on arrival. config.json is not, and Git would have to write the branch's version over yours. git diff --stat main feature/timeouts shows exactly which files are in the overlap.
Fix 1: stash, switch, pop
The usual answer when the edit belongs on the other branch, or you just need it out of the way for a minute. Give the stash a message; an unnamed WIP on main is the kind you forget about.
$ git stash push -m "wip: retries"
Saved working directory and index state On main: wip: retries
$ git switch feature/timeouts
Switched to branch 'feature/timeouts'
$ git stash pop
Auto-merging config.json
CONFLICT (content): Merge conflict in config.json
The stash entry is kept in case you need it again.
The pop conflicted because both sides touched config.json, which is exactly what caused the error, so expect it. The file now holds both versions between <<<<<<< Updated upstream (the branch) and >>>>>>> Stashed changes (yours). Edit it to what you want, then mark it resolved and drop the stash yourself, because a conflicted pop does not:
git add config.json
git stash drop
git add stages the file; git restore --staged config.json afterwards if you want it back as an unstaged edit. If the stash list keeps growing on you, finding forgotten stashes covers how to audit them.
Fix 2: commit it where it is
If the edit belongs on the branch you are leaving, a work-in-progress commit is simpler than a stash and cannot be forgotten. Squash or amend it later.
$ git commit -am "wip: retries"
[main a8eaad5] wip: retries
1 file changed, 1 insertion(+), 1 deletion(-)
$ git switch feature/timeouts
Switched to branch 'feature/timeouts'
Back on main, git reset --soft HEAD~1 turns the WIP commit back into staged changes if you would rather it never existed.
Fix 3: carry it across with checkout -m
git checkout -m (or git switch -m) does a three-way merge of your edit into the target branch during the switch. It is the stash-and-pop sequence in one step, including the conflict:
$ git checkout -m feature/timeouts
Switched to branch 'feature/timeouts'
M config.json
$ git status --short
UU config.json
The markers are labelled feature/timeouts and local. Resolve and git add as above. Best when the edit belongs on the other branch; if you only wanted a quick look, you now have a conflict to clean up first.
Fix 4: throw the edit away
Look before you do this. git restore discards without confirmation and the change is not recoverable from Git afterwards.
$ git diff
@@ -1,4 +1,4 @@
{
"timeout": 30,
- "retries": 1
+ "retries": 3
}
$ git restore config.json
$ git switch feature/timeouts
Switched to branch 'feature/timeouts'
The untracked variant
A close cousin appears when a file you created but never added exists as a tracked file on the target branch:
$ git status --short
?? NOTES.md
$ git switch feature/docs
error: The following untracked working tree files would be overwritten by checkout:
NOTES.md
Please move or remove them before you switch branches.
Aborting
Same cause, same choices. Rename the file, or git stash push -u to stash untracked files along with everything else. Often it is a generated file somebody committed on the other branch; delete yours and move on.
Stop hitting it
Run git status before switching rather than after. If you keep two branches active at once, give the second one its own directory with git worktree add ../app-timeouts feature/timeouts; each worktree has its own working tree and index, so nothing has to be stashed to move between them.
How GitMon shows it
GitMon reads each repository's index and working tree and puts a dirty badge with the file count on any repo that has uncommitted changes; the Dirty filter narrows the list to those. Opening a repo lists each file under Uncommitted Changes with its status (modified, untracked, staged, deleted, conflicted), so you can see what a switch would run into before you type it. The same row shows a stash count, which is where a stash you forgot to pop turns up. The list refreshes once a minute and GitMon never stashes, restores or switches branches for you; use the commands above.