“文件系统冲突”源于windows ntfs或wsl2共享目录对大小写、unicode归一化等处理不一致,导致git索引与磁盘文件状态不匹配;需用git status --ignored和ls -la比对,再通过git rm --cached && git add .同步索引与实际文件状态。

为什么 git checkout 或 git switch 会报“文件系统冲突”?
这不是 Git 本身的逻辑冲突,而是底层文件系统(尤其是 Windows NTFS 或某些挂载的网络盘、WSL2 与 Windows 共享目录)对大小写、Unicode 归一化或长路径处理不一致导致的。Git 认为两个分支里同名文件的 inode/权限/大小写状态不兼容,无法安全覆盖,于是拒绝更新索引,错误信息常含 unable to create file、index lock failed 或 concurrent read/write 类提示。
- 典型场景:从
feature/login切到main,Git 想删掉src/utils/Helper.js,但文件系统里实际存在的是src/utils/helper.js(大小写差异) - WSL2 用户常见于
/mnt/c/下项目目录——Git 在 Linux 层面操作,但 Windows 文件系统不区分大小写,且缓存行为不稳定 -
core.ignorecase = true虽默认开启,但仅影响匹配逻辑,不解决底层重命名/覆盖时的原子性问题
先确认冲突根源:用 git status --ignored 和 ls -la 对比
别急着硬切分支,先看 Git 看到了什么、文件系统实际是什么:
- 运行
git status --ignored,检查是否有被忽略但实际存在的文件干扰了索引(比如 IDE 自动生成的.idea/或.DS_Store) - 在终端里用
ls -la src/utils/(Linux/macOS)或dir src\utils\(Windows CMD),确认真实文件名大小写是否与 Git 记录一致 - 执行
git ls-files --stage | grep -i helper,查 Git 索引里记录的精确路径和 mode(如100644),对比磁盘实际内容
如果发现索引里是 Helper.js,而磁盘是 helper.js,这就是根源——Git 不敢贸然删/重命名,怕丢数据。
安全清理索引:用 git rm --cached + 手动同步
目标不是强行覆盖,而是让索引和磁盘达成一致。最稳的做法是“清空索引再重建”:
- 先备份当前未提交改动:
git stash push --include-untracked - 清掉所有缓存但保留工作区文件:
git rm -r --cached . - 重新添加全部(此时 Git 会按真实文件系统读取):
git add . - 再切分支:
git switch main或git checkout main
注意:git rm --cached 不删磁盘文件,只清索引;git add . 会按当前目录真实状态重建索引,自动适配大小写和 Unicode 归一化规则。
长期规避:调整 Git 配置 + 避开高危路径
这类问题反复发生,说明环境配置或项目存放位置有隐患:
- Windows 用户禁用 NTFS 大小写敏感:
fsutil file setCaseSensitiveInfo C:\path\to\repo disable(需管理员权限) - WSL2 用户绝不要把 repo 放在
/mnt/c/下——改用~/projects/(即 WSL2 原生 ext4 分区) - 全局设
core.autocrlf=false和core.eol=lf,避免换行符引发的隐式文件变更 - 团队统一约定:禁止同一目录下出现仅大小写不同的文件名(如
API.js和api.js)
真正麻烦的从来不是命令怎么敲,而是你正在操作的那个目录,其实已经被文件系统悄悄“动过手脚”了——盯住 git ls-files 和 ls 的输出差异,比背命令重要得多。











