在 Windows 和默认 macOS 文件系统(大小写不敏感)上改文件名大小写,Git 不会把它识别为 rename,而是把两个文件都保留在仓库里。
症状
执行 git pull 时出现:
warning: the following paths have collided (e.g. case-sensitive paths
on a case-insensitive filesystem) and only one from the same
colliding group is in the working tree:
'app/substation/controller/RiderAuditController.php'
'app/substation/controller/RiderauditController.php'
原因
Git 内部是大小写敏感的,仓库里可以同时存在两个文件:
RiderAuditController.php
RiderauditController.php
但 Windows(NTFS)和 macOS(APFS 默认)认为它们是同一个文件,检出时只能保留一个,发生碰撞。
通常是有人在 Windows 上直接改了文件名大小写,Git 把旧文件和新文件都提交进去了。
确认仓库状态
在任意环境执行:
git ls-files | grep -i rideraudit
如果输出两行就说明仓库里确实存在两个文件:
app/substation/controller/RiderAuditController.php
app/substation/controller/RiderauditController.php
解决步骤(必须在 Linux 或 WSL2 上操作)
Windows/macOS 文件系统无法同时持有两个大小写不同的文件,操作只能在大小写敏感环境中完成。
方案一:Linux 服务器(推荐)
# SSH 到 Linux 服务器,确认两文件内容
diff app/substation/controller/RiderAuditController.php \
app/substation/controller/RiderauditController.php
# 删除要废弃的文件(以删除大写版为例)
git rm app/substation/controller/RiderAuditController.php
git rm phalapi/src/rider/Model/RiderAudit.php
git commit -m "fix: remove duplicate case-sensitive files"
git push
方案二:WSL2(Windows 用户)
wsl
cd /mnt/c/projects/your-repo
git rm app/substation/controller/RiderAuditController.php
git commit -m "fix: remove duplicate case-sensitive files"
git push
push 之后,Windows/macOS 成员再 git pull 就不会再有冲突。
如果两个文件内容不同
先比较差异:
git diff --no-index \
app/substation/controller/RiderAuditController.php \
app/substation/controller/RiderauditController.php
查看哪个是最新版本再决定保留哪个。也可以用 git log 看提交历史:
git log --follow -- app/substation/controller/RiderAuditController.php
git log --follow -- app/substation/controller/RiderauditController.php
不推荐的绕过方式
- macOS 创建大小写敏感卷(APFS Case-sensitive)
- Windows 开启目录大小写敏感:
fsutil file setCaseSensitiveInfo . enable
这两种方式只解决当前机器的问题,团队里其他 Windows/macOS 开发者继续会出问题。根本解决办法是清理远程仓库中的重复文件。
PHP 框架的额外风险
PHP 的 PSR-4 自动加载依赖文件名映射,如果保留了小写文件名但代码里用的是大写类名:
new Model_RiderAudit(); // 加载 RiderAudit.php
在 Linux 上 autoloader 找不到文件会报 Class not found。
解决后建议全局搜索:
grep -R "RiderAudit\|Rideraudit" . --include="*.php"
确认所有引用和文件名一致。
