LearnDevOpsHands-On Labs
Troubleshooting Matrix/error: Your local changes to the following files would be overwritten by merge
GitHigh Severity

error: Your local changes to the following files would be overwritten by merge

Fix "Your local changes would be overwritten by merge": run git stash, pull, then git stash pop. Or commit first, or discard with git restore. Pick by intent.

Observed Error Signature / Log Pattern
error: Your local changes to the following files would be overwritten by merge:

Incident Overview

Fix "Your local changes would be overwritten by merge": run git stash, pull, then git stash pop. Or commit first, or discard with git restore. Pick by intent.

easy fix·6 min read

By Vishvesh Patel·DevOps Engineer·Updated 21 September 2026

BASHDiagnostic / remediation command
error: Your local changes to the following files would be overwritten by merge:
        src/config.ts
Please commit your changes or stash them before you merge.
Aborting

error: Your local changes to the following files would be overwritten by checkout:
        package.json
Please commit your changes or stash them before you switch branches.

Do this first3 steps

Run these in order. Each one tells you what its output means before you change anything.

• See exactly what is uncommitted before deciding

The M column is modified and unstaged, and the files listed in the error are a subset of these. Read the diff before choosing: the difference between keeping and discarding this work is not recoverable in one direction.

• Keep the changes and get the remote commits

If stash pop reports a conflict, your work and the incoming commits touched the same lines. The stash is kept until the conflict is resolved, so nothing is lost.

• Or discard them, if the changes are genuinely disposable

This overwrites the file from the index with no confirmation and no reflog entry. Uncommitted changes discarded this way cannot be recovered.

Git is refusing to overwrite work you have not committed. The merge would replace those files with the incoming versions, and your edits would be gone with no way back, so it stops first.

This is Git being careful. The fix is to decide what happens to those changes.

BASHDiagnostic / remediation command
git status --short && git diff --stat

Look before you choose

The first column is the index, the second is the working tree. M means modified and not staged. ?? is untracked, and untracked files are not what triggered this error.

Then read the actual diff:

Often this is a local port number or a debug line you do not need. Sometimes it is an afternoon of work. The four options below differ in whether that survives, and only you can tell them apart.

BASHDiagnostic / remediation command
git status --short

Option 1: Stash, pull, restore

The usual answer when the changes matter and are not ready to commit:

git stash pop applies the stash and drops it. If applying produces a conflict, the stash is not dropped and stays in the list until you resolve things, so nothing is lost.

Two things worth knowing:

BASHDiagnostic / remediation command
git stash push -m "wip before pull"
git pull
git stash pop

Option 2: Commit first

If the work is coherent, committing is cleaner than stashing:

--rebase replays your commit on top of the incoming ones rather than creating a merge commit, which keeps the history readable for a small change.

If the commit is not finished, commit it anyway and amend later:

Only amend commits you have not pushed.

BASHDiagnostic / remediation command
git add -A
git commit -m "Add retry to the payment client"
git pull --rebase

Option 3: Discard the changes

When the diff is genuinely disposable:

git restore replaced git checkout -- <file> in Git 2.23 and is worth using because it cannot be confused with switching branches.

There is no undo. Uncommitted changes are not in the object database, so the reflog cannot help. Read the diff first.

To clear untracked files as well:

git clean -fd deletes untracked files permanently, including ones you meant to keep and never added. The -n dry run is not optional in practice.

BASHDiagnostic / remediation command
git restore src/config.ts        # one file
git restore .                    # everything tracked

Option 4: Take theirs for specific files

A middle path when you want the remote version of one file and your own for everything else:

That overwrites just src/config.ts from the remote, leaving your other changes intact.

BASHDiagnostic / remediation command
git checkout origin/main -- src/config.ts
git pull

The one that keeps coming back

If the same file is modified every time you pull and you never edited it, it is a tracked file that should not be tracked. Adding it to .gitignore does nothing, because .gitignore only affects untracked files.

--cached removes it from Git and leaves it on disk. Without it, you delete the file.

Common culprits: .env, .vscode/settings.json, *.log, and build output someone committed once.

Where a file must be tracked but is locally modified on purpose, such as a sample config, the honest pattern is to track config.example.json and gitignore the real one. git update-index --skip-worktree also exists and is a recurring source of confusion, since the change becomes invisible to git status and reappears in inexplicable ways later.

BASHDiagnostic / remediation command
git rm --cached .env
echo ".env" >> .gitignore
git commit -m "Stop tracking .env"

The checkout variant

Switching branches produces the same error:

Same causes, same options. Git allows the switch when the changed files do not differ between the two branches, which is why it sometimes works and sometimes does not.

git switch is the modern command for this and gives clearer messages than git checkout:

Since Git 2.27 you can also carry your changes across with a merge:

BASHDiagnostic / remediation command
error: Your local changes to the following files would be overwritten by checkout:
        package.json

A checklist

Frequently Asked Questions

Why does Git block a pull instead of just merging?

Because the merge would overwrite files you have modified and not committed, and uncommitted changes exist nowhere else. Committed work can always be recovered through the reflog even after a bad merge or reset, but a working-tree edit that gets overwritten is simply gone. Git stops and asks you to commit or stash precisely because it cannot offer you an undo for this one. Untracked files do not trigger it, since there is nothing of yours to overwrite.

What is the difference between git stash and committing?

A commit is a permanent, named point in history that you can push, share and recover through the reflog. A stash is a local side-stack, invisible to everyone else, intended for work in progress you do not want in the history yet. For anything you might want back in a week, commit; you can always rewrite the message later with git commit --amend or squash it during a rebase. Stash is best for the five-minute interruption, and stashes are easy to accumulate and forget, so give them messages with -m.

Can I recover changes I discarded with git restore?

Generally no. Uncommitted changes were never written to Git's object database, so there is no reflog entry and no dangling object to recover. The realistic chances are your editor's local history, which VS Code and the JetBrains IDEs both keep, or a filesystem snapshot such as Time Machine. This is the reason to read git diff before discarding anything, and the reason git stash is worth the extra few seconds when you are not certain.

Why does the same file keep appearing as modified when I never edit it?

It is tracked by Git and being changed by something else: a tool rewriting .vscode/settings.json, a build step touching a committed artefact, or an .env file that was committed once. Adding it to .gitignore has no effect, because .gitignore only applies to files Git is not already tracking. Stop tracking it with git rm --cached <file>, which removes it from the repository while leaving it on disk, then add it to .gitignore and commit both changes together.

What happens if git stash pop hits a conflict?

The conflicting files are left with conflict markers for you to resolve, and, importantly, the stash entry is not dropped. You can see it still in git stash list, so nothing is lost and you can start again with git checkout -- . followed by another git stash pop if the resolution goes wrong. Once you have resolved and staged the files, remove the entry yourself with git stash drop. Using git stash apply instead of pop makes this explicit, since it never drops the stash automatically.

Reference and practice

Learn the underlying concept

Other Git errors

Free, comprehensive DevOps tutorials and learning roadmaps. Master Docker, Kubernetes, CI/CD, and more.

Get notified about new tutorials and features.

• Roadmaps

• Interview Prep

• Certifications

• Company

© 2026 DevOpsLesson. All rights reserved.

Need to practice this scenario?

Simulate this error condition and practice recovery commands safely in our in-browser terminal.

Open Git Sandbox