Overview & Root Cause Summary: The error
error: Entry 'occurs during' not uptodate. Cannot merge. fatal: merging of trees and failed git merge,git pull, orgit checkout -mwhen Git detects that a tracked file in your working tree has uncommitted modifications that conflict with incoming changes. In many instances, this error is triggered not by actual textual edits, but by stale index metadata (cached file stat timestamps modified by build tools, linters, or clock skew) or executable file-mode permission changes.
Understanding the Root Causes
- Uncommitted Local Modifications: The target file contains uncommitted working tree edits that directly overlap with incoming commits from the branch being merged.
- Stale Index Stat Cache: Compilers, watchers, or IDE formatters touched the file’s modification timestamp (mtime) without changing its contents, causing Git’s cached index to assume the file is dirty.
- File Permission (Executable Bit) Drifts: Changes to file permission modes (e.g., toggling between
100644and100755), especially across Windows and Linux environments, flagging the file as modified. - Submodule Pointer Desynchronization: A submodule folder pointing to a different commit hash than the one recorded in the staging index.
Step 1: Quick Fix (Refresh Index Stat Cache & Stash Changes)
Refresh Git’s internal index cache to resolve false-positive timestamp mismatches, or temporarily stash genuine modifications.
# 1. Refresh the index stat cache (resolves timestamp-only discrepancies immediately):
git update-index --refresh
# 2. Check if the file is still marked as modified:
git status
# 3. If genuine uncommitted changes exist, stash them safely:
git stash push -m "WIP before merge"
# 4. Re-run your merge or pull command:
git merge
# 5. Restore your stashed changes:
git stash pop
Step 2: Committing Changes or Discarding Unneeded Edits
If the modifications are intentional, record them into a commit prior to merging; otherwise, discard them to align with the current HEAD.
# Option A: Commit intentional local changes before merging:
git add
git commit -m "chore: save local modifications before merge"
git merge
# Option B: Discard local modifications if they are expendable:
git restore
# (For older Git versions < 2.23):
# git checkout --
git merge
Step 3: Handling File Mode (Permission) & Submodule Collisions
Configure Git to ignore executable bit alterations caused by cross-platform file transfers, or synchronize desynchronized submodule commits.
# 1. Ignore filesystem permission bit alterations (common in Windows/WSL/Docker):
git config core.fileMode false
# 2. If the entry is a desynchronized submodule, update it to the recorded commit:
git submodule update --init --recursive
# 3. Soft reset the staging index to clear cached lock artifacts:
git reset HEAD
Verification & Testing Steps
Confirm that the merge successfully completes and verify that working tree status is clean.
# 1. Check working tree status:
git status
# 2. Confirm the merge commit in repository history:
git log --graph --oneline -n 3
# 3. Verify no lingering conflict markers exist:
git diff
Summary Comparison Table
| Remediation Strategy | Applied Command | Working Tree Data Impact | Recommended Scenario |
|---|---|---|---|
| Index Refresh | git update-index --refresh |
Zero data change | Build tools or editors touched mtime without edits |
| Git Stash | git stash push && git stash pop |
Preserves work in stash stack | Genuine uncommitted work you need to keep |
| Discard Edits | git restore |
Permanently deletes local edits | Unwanted scratch changes or auto-generated files |
Disable core.fileMode |
git config core.fileMode false |
Ignores chmod +x changes |
Cross-platform Windows/WSL/Docker permission drifts |
Leave a Reply