答案是文件可执行位(executable bit)不一致导致的误报,git将权限变化视为修改;运行git ls-files --stage查看权限值差异,执行git config core.filemode false后git reset --hard即可解决。

git merge 报错 “error: Your local changes to the following files would be overwritten by merge” 但没改过文件
这通常不是真有本地修改,而是 Git 检测到工作区文件的可执行位(executable bit)和暂存区/远程分支不一致。Linux/macOS 默认跟踪 chmod 变化,Windows Git 默认忽略——跨平台协作时尤其常见。
- 用
git status查看报错文件是否标为modified:,但git diff无内容输出 → 基本就是可执行位差异 - 确认是否真被改过:运行
git ls-files --stage <file></file>,看第三列权限值(如100644vs100755) - 临时关闭可执行位追踪(仅限当前仓库):
git config core.filemode false,之后git reset --hard即可清理“假修改”
为什么 git merge 会因可执行位冲突而中断
Git 把文件权限(尤其是 0755 和 0644)当作元数据的一部分参与三路合并。如果 base、ours、theirs 三方在同一个文件的可执行位上不一致,Git 无法自动决定保留谁的,就会中止合并并报错。
- 常见触发场景:有人在 macOS 上
chmod +x deploy.sh后提交;你在 Windows 上拉取后又尝试合并新分支 → 你的工作区文件权限被 Git 自动重置为0644,但索引里仍是0755 -
git merge --no-commit不跳过权限检查,--no-ff也无效 —— 权限冲突必须显式解决 - 不能靠
git checkout --theirs直接覆盖权限,它只处理内容,不改 mode
安全修复可执行位冲突的三种操作方式
目标是让索引、工作区、目标分支的权限达成一致,且不破坏脚本执行能力。
部署一个包含 4 个智能体(agent)的数字孪生平台。在以下情况下使用该技能: 1. 用户希望为物理资产监控与预测性维护等场景搭建数字孪生系统……
- 方案一(推荐):统一按目标分支设权限 → 先
git merge --no-commit <branch></branch>,再对冲突文件执行git checkout <branch> -- <file></file></branch>(注意:这是 checkout 文件内容+权限) - 方案二:手动修正单个文件 →
chmod 0755 <file></file>后git add <file></file>,再git commit(适合少量关键脚本) - 方案三:批量同步所有脚本权限 →
find . -name "*.sh" -exec chmod 0755 {} \;,然后git add -u提交变更(慎用,确保不会误改非脚本文件)
长期规避可执行位问题的配置建议
团队协作中,靠每次手动修权限不现实。关键是统一策略,而非掩盖问题。
- 所有成员执行:
git config --global core.filemode false(Windows/macOS 都适用,Git 2.30+ 默认已启用) - 在项目根目录加
.gitattributes文件,明确声明哪些文件必须保持可执行位:*.sh text eol=lf executable<br>*.py text eol=lf
- CI 流水线中加入检查:
git ls-files -v | grep "^X" | cut -d' ' -f2-列出所有被标记为可执行但未设置权限的文件,及时发现遗漏
可执行位本身不是 bug,是 Git 对 Unix 文件模型的忠实实现。问题常出在开发环境混杂、缺乏约定,而不是工具本身。真正麻烦的不是怎么修一次,而是没人知道该由谁、在哪个环节保证权限一致性。










