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

二进制文件冲突不报错,是因为Git根本没尝试合并
Git对.psd、.xlsx、.pdf这类文件,只看前800字节是否含\0——一旦判定为二进制,就直接禁用diff和合并逻辑。它不会输出CONFLICT (content),也不会在VSCode里渲染红蓝块,只是静默把两个版本都留在工作区,标记为unmerged。
后果很具体:
-
git status显示both modified,但git diff无输出 -
git mergetool不弹窗(除非你配了支持二进制的外部工具) - 编辑器内联冲突UI完全不加载,“Accept Current Change”按钮压根不出现
用checkout --ours/--theirs时,--不能省
执行git checkout --ours -- path/to/logo.png不是“覆盖文件”,而是向Git声明:“我已决定保留这个版本”。漏掉末尾的--,Git会把路径误当成参数,可能报错或删错文件。
还要注意两件事:
- 执行后必须立刻
git add path/to/logo.png——Git只认暂存状态,不看你文件内容是否已被替换 - 在
rebase场景下,--ours指rebase目标分支(即“上游”),含义和merge相反,容易搞反
.gitattributes提前声明binary比事后补救更可靠
等冲突发生再手动选,容易漏、容易忘git add,更糟的是CI跑挂才发现PDF被两人同时改过。更稳的做法是项目初始化阶段就写好.gitattributes:
使用约定式提交信息暂存、提交和推送git更改。当用户想要提交和推送更改、提到推送到远程、或要求保存并推送工作时触发。也适用于用户说“推送更改”、“提交并推送”、“推送这个”、“推送到github”或类似git工作流程请求时。
*.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-lfs并git lfs install,否则指针文件会变空 -
git clone默认只拉指针,要git lfs pull才下载真实内容 - CI环境需额外配置
git lfs install --skip-smudge避免拉全量大文件
真正难处理的从来不是“怎么选版本”,而是“怎么让Git别把两个版本都塞进工作区还假装没事”。.gitattributes和git lfs不是可选项,是协作前提。

















