Fix: Git "Your local changes would be overwritten by merge"
Quick Answer
How to fix Git error 'Your local changes to the following files would be overwritten by merge' using git stash, commit, checkout, and pull strategies.
The Error
You run git pull or git merge and get:
error: Your local changes to the following files would be overwritten by merge:
src/config.js
src/utils/helpers.ts
Please commit your changes or stash them before you merge.
AbortingOr during git checkout:
error: Your local changes to the following files would be overwritten by checkout:
src/app.js
Please commit your changes or stash them before you switch branches.
AbortingOr during git rebase:
error: cannot rebase: You have unstaged changes.
Please commit or stash them.Git is protecting your work. You have uncommitted changes in files that the incoming merge, checkout, or rebase would also modify. Git refuses to proceed because it would overwrite your local edits.
Why This Happens
Git needs to modify files in your working directory to complete the operation (merge, pull, checkout, or rebase). If those files have uncommitted changes, Git has a conflict: your local edits versus the incoming changes. Rather than silently losing your work, Git aborts the operation.
This happens in these scenarios:
- You edited files and then ran
git pullbefore committing. - You are switching branches that have different versions of files you modified.
- You are rebasing onto a branch that touches the same files.
- An IDE or build tool modified files automatically (like
package-lock.json,.DS_Store, or generated configs).
The fix depends on whether you want to keep your changes, discard them, or save them temporarily.
Fix 1: Stash Your Changes, Then Pull
The most common fix. Git stash temporarily saves your changes, lets you pull, then reapplies them.
git stash
git pull
git stash popStep by step:
git stash— saves your uncommitted changes and reverts the working directory to the last commit.git pull— pulls the latest changes from the remote (now succeeds because no local changes conflict).git stash pop— reapplies your stashed changes on top of the pulled code.
If git stash pop causes merge conflicts, Git tells you which files conflict. Resolve them manually, then:
git add <resolved-files>
git stash drop # Remove the stash entry after resolvingFor detailed conflict resolution during stash pop, see Fix: git stash pop conflicts.
Pro Tip: Use
git stash -uto also stash untracked files (new files that haven’t been added to Git). Without-u, untracked files are left behind and can sometimes cause issues during merge.
Fix 2: Commit Your Changes First
If your changes are ready to keep, commit them before pulling:
git add -A
git commit -m "WIP: save current work before pulling"
git pullIf the pull introduces conflicts with your committed changes, Git starts a merge. Resolve the conflicts:
# Edit the conflicting files
git add <resolved-files>
git commit -m "Merge remote changes"This approach creates a clean history where your changes and the remote changes are both preserved. If you prefer a linear history, use git pull --rebase instead (see Fix 5).
Fix 3: Discard Your Local Changes
If you don’t need your local changes and just want the remote version, discard them:
Discard changes to specific files:
git checkout -- src/config.js src/utils/helpers.tsOr with newer Git (2.23+):
git restore src/config.js src/utils/helpers.tsDiscard all uncommitted changes:
git checkout -- .Or:
git restore .Then pull:
git pullWarning: Discarded changes are gone forever. Git does not keep a backup of uncommitted changes. Make sure you truly don’t need them before discarding. If you are unsure, use stash (Fix 1) instead — you can always drop the stash later.
Fix 4: Stash Specific Files
If you want to keep some changes and discard others, stash only specific files:
git stash push -m "save config changes" src/config.jsThis stashes only src/config.js. Other modified files remain in your working directory.
Then resolve the remaining files:
git checkout -- src/utils/helpers.ts # Discard this one
git pull
git stash pop # Restore the stashed config changesYou can also use git stash push with --patch to selectively stash individual hunks within files:
git stash push -pGit interactively asks which changes to stash and which to keep.
Fix 5: Use git pull —rebase
If you prefer a linear commit history without merge commits:
git stash
git pull --rebase
git stash popOr commit first, then rebase:
git add -A
git commit -m "WIP: my changes"
git pull --rebase--rebase replays your commits on top of the remote changes instead of creating a merge commit. This keeps the history cleaner.
If conflicts arise during rebase, resolve them and continue:
# Edit conflicts
git add <resolved-files>
git rebase --continueFor more complex rebase scenarios, see Fix: git rebase conflicts.
To make rebase the default for git pull:
git config --global pull.rebase trueFix 6: Add Generated Files to .gitignore
If the conflicting files are generated artifacts — build output, lock files, IDE configs — they probably should not be tracked by Git in the first place.
Common culprits:
.DS_Store(macOS)Thumbs.db(Windows)*.pyc,__pycache__/(Python).idea/,.vscode/settings.json(IDE settings)dist/,build/,.next/(build output)*.log(log files)
Add them to .gitignore:
.DS_Store
Thumbs.db
*.pyc
__pycache__/
.idea/
dist/
build/
*.logThen remove them from tracking (without deleting the files):
git rm --cached .DS_Store
git rm --cached -r .idea/
git commit -m "Stop tracking generated files"After this, Git no longer tracks these files, and they won’t cause merge conflicts.
Common Mistake: Adding files to
.gitignoreafter they are already tracked does nothing. You must alsogit rm --cachedthem. The.gitignorefile only affects untracked files.
Fix 7: Handle package-lock.json Conflicts
package-lock.json is a frequent source of this error. It changes whenever you npm install, and pulling someone else’s changes often conflicts.
Option 1: Accept theirs and regenerate:
git checkout --theirs package-lock.json
npm install
git add package-lock.jsonOption 2: Stash, pull, reinstall:
git stash
git pull
npm install # Regenerates lock file with merged dependencies
git add package-lock.json
git commit -m "Update package-lock.json after merge"
git stash popFix 8: Force Checkout (Nuclear Option)
If you want to switch branches and don’t care about any local changes:
git checkout -f <branch-name>Or:
git reset --hard
git checkout <branch-name>Warning: git reset --hard permanently discards all uncommitted changes — both staged and unstaged. There is no recovery. Only use this when you are certain you don’t need any local changes.
If you end up in a detached HEAD state after a forced checkout, see Fix: git detached HEAD.
Still Not Working?
If the error persists after trying the fixes above:
Check for case-sensitivity conflicts. On macOS/Windows, Config.js and config.js are the same file. On Linux, they are different. This can cause phantom “changes” that Git reports as modified even though you haven’t edited them.
Check line ending settings. If core.autocrlf is converting line endings, Git may report files as modified even though the content is the same:
git config core.autocrlfSet it consistently:
git config --global core.autocrlf input # Linux/macOS
git config --global core.autocrlf true # WindowsCheck for file permission changes. On some systems, Git tracks file permission changes. If a file’s executable bit changed, Git reports it as modified:
git config core.fileMode false # Ignore permission changesCheck for git hooks or IDE auto-formatting. Pre-commit hooks or IDE format-on-save can modify files right after you stage them, causing unexpected changes. Disable auto-format temporarily to test.
Use git diff to see what changed:
git diff src/config.jsThis shows exactly what is different between your local file and the last commit. If the diff looks unexpected (whitespace changes, line endings), the issue is likely in your editor or Git configuration, not in your code.
If none of this helps and you need to force push after resolving, see Fix: git push rejected non-fast-forward. But be cautious — force push overwrites remote history.
For merge conflicts that arise after successfully pulling, see Fix: git merge conflict resolution.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: Git "cannot lock ref" – Unable to Create Lock File
How to fix the Git error 'cannot lock ref: Unable to create .git/refs/heads/branch-name.lock' caused by stale lock files, case conflicts, packed-refs corruption, and concurrent operations.
Fix: Git fatal: not a valid object name: 'main'
How to fix Git fatal not a valid object name error caused by empty repositories, wrong branch names, missing initial commits, and corrupted refs.
Fix: fatal: remote origin already exists
How to fix the 'fatal: remote origin already exists' error in Git by updating the remote URL, removing and re-adding origin, managing multiple remotes, and handling forked repos.
Fix: Git LFS Smudge Filter Error
Resolve Git LFS smudge filter errors by installing Git LFS, fixing credentials, resetting LFS hooks, and handling bandwidth or storage quota issues.