git 将 chmod 视为内容冲突是因为 core.filemode 机制默认追踪文件权限变更,当两分支对同一文件设置不同执行权限(如 0644 vs 0755)时,即使内容完全一致也会触发冲突;可通过 git status、git ls-files --stage 和 ls -l 检查确认,推荐全局或本地关闭 core.filemode false 来避免误报。

git merge 为什么把 chmod 当成内容冲突
Git 默认把文件权限(如 0755 vs 0644)当作可追踪变更,一旦两个分支对同一文件设置了不同执行权限,git merge 就会触发“冲突”,哪怕文件内容完全一致。这不是内容冲突,而是 Git 的 core.filemode 机制在起作用。
检查是否真有权限冲突
先确认是不是权限惹的祸,而不是代码改了:
- 运行
git status,如果只显示某文件为 “both modified”,但git diff输出为空或只有old mode/new mode行,基本就是权限问题 - 用
git ls-files --stage 文件名查看两个分支在索引中的 mode 值,比如100644(普通文件)和100755(可执行)并存 - 对比当前工作区、暂存区、HEAD 的权限:执行
ls -l 文件名和git ls-files --stage 文件名,看是否不一致
关闭 filemode 检测(推荐开发机统一配置)
多数团队不需要靠 Git 管理脚本权限,关掉它能避免大量误报:
使用四维度框架评估任意 GitLab MR 或 GitHub PR 的复杂度:规模(20%),认知负荷(30%),审查工作量(30%),风险/影响(20%)...
- 全局关闭(影响所有仓库):
git config --global core.filemode false - 仅当前仓库关闭:
git config core.filemode false - 关掉后,Git 不再记录或比对
chmod变更,git status不再因此标红,git merge也不会因权限差异中断 - 注意:Windows 和 macOS 默认启用
core.filemode,Linux 默认开启;关掉后,执行权限变更需显式git add --chmod=+x 文件名才能提交
临时绕过权限冲突完成合并
如果不能改配置,又急需合完分支,可用以下方式跳过权限校验:
- 合并时忽略权限差异:
git merge -Xignore-space-change --no-commit 分支名(-Xignore-space-change对权限无效,但配合--no-commit可手动修复) - 更直接的做法:先让 Git 接受当前工作区权限,再继续合并:
git add -f 文件名 && git commit --no-edit(前提是内容确实没冲突) - 极端情况可强制使用 ours 策略:
git merge -s ours 分支名,但这会丢弃对方分支所有变更,慎用
权限冲突本身不危险,但容易让人误以为代码有实质冲突而删错逻辑。真正要盯紧的,永远是 和 <code>>>>>> branch-name 之间的那几行代码——那里才藏着人脑必须介入的地方。










