git status 显示 both modified 但无红蓝冲突标记,是因为 git 将 .psd、.xlsx 等文件识别为二进制,自动禁用合并与 diff,仅标为 unmerged;需通过 .gitattributes 声明 binary 或启用 git lfs 来规范处理。

git status 显示 both modified 但没红蓝块,是二进制冲突
Git 遇到 .psd、.xlsx、.fbx 这类文件冲突时,根本不会输出 CONFLICT (content),也不会在 VSCode 或 TortoiseGit 里渲染冲突标记——它只是静默跳过合并逻辑,把两个版本都留在工作区,状态标为 unmerged。
典型表现就是:git status 显示 both modified,但你看不到任何差异行;git mergetool 不弹窗;编辑器里“Accept Current Change”按钮压根不出现。
这是因为 Git 用文件头前 800 字节是否含 \0 来判定二进制,一旦触发,就禁用 diff 和 merge,只留一句 Binary files a/file.pdf and b/file.pdf differ。
- 别指望靠肉眼比对文件内容——字节流没法读
- 别反复
git add尝试刷新状态——它不认内容,只认暂存区是否已标记解决 - 执行
git checkout --ours或--theirs后,必须立刻跟git add path/to/file,否则 Git 仍认为冲突未解决
用 git checkout --ours/--theirs 选版本前先确认语义
git checkout --ours -- path/to/logo.png 看似简单,但容易踩坑:在 rebase 场景下,--ours 指的是 rebase 目标分支(即“上游”),和 merge 中的含义相反。美术改完 ui.sketch 后执行 git rebase main,再用 --ours,实际保留的是 main 上的老版本。
更稳妥的做法是先查清楚谁改了什么:
- 用
git log --oneline --graph --all -- path/to/file看两个分支各自最后一次提交 - 用
git ls-files -s path/to/file查两个版本的 object hash,再用git show <hash> > file_v1</hash>导出对比(需配合外部工具) - 如果团队用 Git LFS,直接去 LFS 服务器页面看上传记录和元数据变更时间
.gitattributes 提前声明 binary 是防冲突的第一道防线
等冲突发生再手动选,大概率漏加、忘 git add,CI 跑到一半才发现 report.pdf 被两人同时覆盖。正确姿势是在项目初始化阶段就写好 .gitattributes:
*.psd binary *.xlsx binary *.pdf binary *.fbx binary
这个 binary 关键字等价于 -merge -diff,效果是:
- Git 直接拒绝尝试合并,不再“假装能处理”
-
git status明确标为unmerged - 终端打印
CONFLICT (binary): Merge conflict in file.psd,一眼识别风险点
注意:不要写成 *.psd -text 单独一行——它只影响换行符处理,不关闭合并逻辑。
大体积二进制文件必须上 Git LFS
单个 .blend 文件 800MB,每次 git pull 都要下载完整副本,历史记录膨胀快,冲突解决全靠人工拍板——这不是协作,是硬扛。
Git LFS 把大文件替换成指针,真正内容存在远程 LFS 服务器:
- 运行
git lfs install启用 LFS - 运行
git lfs track "*.psd"声明跟踪规则(会自动更新.gitattributes) - 提交后,
git push会把真实文件上传到 LFS 服务,本地只留轻量指针
关键点:LFS 不解决“谁的修改该保留”,但它让冲突变得可管理——至少你不用每次拉代码都等十分钟,也不用担心仓库体积突破 2GB 被平台限速。
真正难的从来不是命令怎么敲,而是美术改图层、程序调参数、产品调文案,三个人同时动同一个 .unity 场景文件时,没人能靠 --ours 拍板决定最终形态。提前约定协作流程,比事后救火重要得多。











