git对二进制文件冲突不报错也不标红,是因为其依据文件头800字节是否含\0判定为二进制后,直接禁用diff和合并逻辑,仅静默保留双方版本并标记unmerged,导致git status显示both modified但无差异细节、mergetool不弹窗、vscode不渲染红蓝块。

Git为什么对二进制文件冲突不报错也不标红
Git遇到.psd、.xlsx、.pdf这类文件冲突时,根本不会输出CONFLICT (content),也不会在VSCode里渲染红蓝块——它只是静默跳过合并,把两个版本都留在工作区,并标记为unmerged。原因在于:Git用文件头前800字节是否含\0来判定二进制,一旦触发,就禁用diff和合并逻辑,只输出Binary files a/file.pdf and b/file.pdf differ。
后果很直接:
-
git status显示both modified,但你看不到任何差异细节 -
git mergetool不弹窗(除非你额外配了支持二进制的外部工具) - VSCode/IDEA等编辑器的内联冲突UI完全不加载,“Accept Current Change”按钮都不出现
用git checkout --ours或--theirs强制选版本
这是最常用也最容易出错的操作。核心不是“覆盖文件”,而是“告诉Git你已做决策”。
保留当前分支版本:git checkout --ours -- path/to/logo.png
保留对方分支版本:git checkout --theirs -- path/to/report.xlsx
注意三点:
- 命令末尾的
--不能省——否则Git会把路径误当成参数,可能报错或删错文件 - 执行后必须立刻
git add path/to/logo.png——Git只认暂存状态,不看你文件内容是否已被替换 - 在
rebase场景下,--ours指rebase目标分支(即“上游”),含义和merge相反,容易搞反
提前用.gitattributes声明binary避免隐式冲突
等冲突发生再手动选,容易漏、容易忘git add,更糟的是CI跑挂才发现PDF被两人同时改过。更稳的做法是在项目初始化阶段就写好.gitattributes:
对 GitHub Actions 工作流 YAML 文件进行 lint 与验证,检查常见错误、安全隐患、已废弃的操作以及最佳实践。适用于要求进行代码检查、验证等场景。
*.psd binary *.xlsx binary *.pdf binary *.sketch binary
binary关键字等价于-merge -diff,效果是:
- Git直接拒绝尝试合并,不再“假装能处理”
-
git status明确标为unmerged - 终端打印
CONFLICT (binary): Merge conflict in file.psd,一眼识别风险点
高频协作场景下优先上git lfs
如果团队要频繁修改设计稿、模型文件或大体积文档,原生Git处理二进制就是硬扛:每次git pull都要下载完整文件,历史膨胀快,冲突解决全靠人工拍板。
git lfs把大文件替换成指针,真正内容存在远程LFS服务器:
- 合并时Git只比对指针文本,不再触发二进制判定逻辑
-
git status能准确显示哪个版本被更新,git diff可读 - VSCode等编辑器能正常识别LFS文件变更并触发UI提示
执行一次git lfs install(全局生效),再git lfs track "*.psd",最后提交.gitattributes即可启用。
真正难的不是选哪个版本,而是让Git别在你没意识到的时候悄悄放弃合并——它不报错,不代表没问题;它没标记,不代表没冲突。










