What this error means
Git blocks a rebase when your working tree has local changes that would be lost or conflicted by applying upstream commits. The error typically looks like:
- error: Your local changes to the following files would be overwritten by rebase: ...
- Please commit or stash them.
You must either save, move, or discard those changes before rebasing.
Quickstart (choose one)
- Keep changes automatically:
- git rebase --autostash origin/main
- Temporarily stash and restore:
- git stash push -u -m "wip"
- git rebase origin/main
- git stash pop
- Commit WIP and rebase:
- git add -A && git commit -m "wip"
- git rebase origin/main
- Optionally squash or reset soft to remove the WIP commit after.
- Discard working changes:
- git restore --staged . && git restore .
- git rebase origin/main
Minimal working example
Reproduce the error, then fix it.
# Setup
mkdir demo && cd demo
git init
git branch -M main
echo "line1" > app.txt
git add app.txt && git commit -m "init"
# Create WIP on feature that is not committed
git checkout -b feature
echo "feature-wip" >> app.txt # uncommitted change
# Upstream change on main touching the same file
git checkout main
echo "main-change" >> app.txt
git commit -am "main: change app.txt"
# Try to rebase; expect the error
git checkout feature
git rebase main # fails: would be overwritten by rebase
# Fix via stash
git stash push -u -m "wip"
git rebase main
git stash pop # may open a conflict to resolve if needed
Step-by-step resolution
- Inspect local state
- git status --porcelain=v1 shows tracked/untracked changes.
- git diff and git diff --staged show what you will keep/discard.
- Pick a strategy
- Keep all changes through rebase: use --autostash or stash manually.
- Keep only some changes: stage desired hunks, stash the rest.
- Discard everything: restore/reset to HEAD.
- Execute
- Autostash (tracked changes):
- git rebase --autostash origin/main
- Manual stash (tracked + untracked):
- git stash push -u -m "wip"
- git rebase origin/main
- git stash pop
- Partial keep:
- git add -p # stage only the hunks you want to keep now
- git stash push -u -m "leftover"
- git rebase origin/main
- git stash pop # re-apply remaining changes
- Discard:
- git restore --staged . && git restore .
- git rebase origin/main
- Resolve conflicts (if any)
- Fix files, then: git add <files> && git rebase --continue
- To stop and revert the rebase: git rebase --abort
Strategy cheat sheet
| Goal | Command(s) |
|---|---|
| Keep everything, low effort | git rebase --autostash origin/main |
| Keep tracked and untracked | git stash push -u; git rebase; git stash pop |
| Keep only specific hunks | git add -p; git stash push -u; rebase; stash pop |
| Discard all working changes | git restore --staged . && git restore .; rebase |
| Isolate work in another directory | git worktree add ../wt main |
Notes on special cases
- Untracked files: The error can also arise when untracked files would be overwritten. Use git stash push -u or move them elsewhere.
- Submodules: Rebase the superproject; update submodules separately. Use git submodule update --recursive after rebase.
- Binary files: Autostash can still stash them, but conflict resolution is all-or-nothing.
- Line endings/permissions: Spurious diffs may block rebase. Normalize via .gitattributes (e.g., text=auto) and ensure core.autocrlf or filemode is set appropriately.
Performance considerations (DevOps scale)
- Prefer --autostash for speed on small repos; on very large repos it adds an extra write/read of the index and working tree. For large changes, committing a WIP may be faster than stashing.
- Enable reusable conflict resolutions: git config rerere.enabled true. This speeds repeated rebases by auto-applying past resolutions.
- Keep the repo healthy:
- git fetch --prune; git maintenance run --auto
- Enable filesystem monitor: git config index.useBuiltinFSMonitor true
- Rebase depth:
- For very large topic branches, rebase in smaller chunks (e.g., onto intermediate tags) to reduce conflict pressure and runtime.
- Monorepos:
- Use sparse-checkout to limit working set: git sparse-checkout set <dirs>
Safer patterns
- Use git pull --rebase --autostash to avoid manual stash/unstash during pulls.
- Protect WIP:
- git stash push -u -m "wip"; after rebase use git stash apply (keeps the stash) instead of pop if you want a backup.
- Avoid dirty trees before long rebases; commit or stash early.
Common pitfalls
- Assuming autostash includes untracked files: It may not. Prefer git stash -u when untracked files are involved.
- Losing work on stash pop conflict: Use git stash apply, resolve, then git stash drop once safe.
- Mixing index state: If you had staged changes, autostash/keep-index semantics can surprise you. Verify with git status after applying.
- Interrupting rebase mid-conflict without abort: Always either git rebase --continue after resolving, or git rebase --abort to roll back.
Tiny FAQ
Q: Can I bypass the check and force rebase? A: No. Git requires you to save or discard local changes first to prevent data loss.
Q: Is committing a WIP bad practice? A: It’s fine locally. After rebase, you can squash or remove it with git reset --soft HEAD~1 if you don’t want it in history.
Q: I get the error on git pull --rebase. Same fix? A: Yes. Use --autostash, stash manually, or commit before pulling.
Q: How do I see what would be overwritten? A: Use git status --porcelain and git diff. For untracked files, try git clean -dn to preview removals.
Q: After stash pop I still have conflicts. What now? A: Resolve conflicts, git add the files, then continue the rebase with git rebase --continue.