之前实习的时候在写完代码上线部署的时候发现服务器 Build 的时候找不到依赖文件,但是在本地 Build 却正常,检查了半天本地明明没有问题,但是服务器上就是报路径错误,让我很是头疼。
最后在大佬帮助 Debug 后发现服务器上面有两个同名文件夹(大小写不同)。例如:ABC
和 abc
两个文件夹,因为服务器是 Linux 系统,而 Linux 系统是区分大小写的,所以两个文件可以同时存在,但是在拉到本地之后,就合并成了一个文件夹 ABC
(因为 Windows 和 macOS(默认) 以及 Git(默认) 是不区分大小写的),这个时候 abc
文件夹在本地是看不见的,合并到了 ABC
文件夹中。
因为本地 abc
文件夹中的所有文件都在 ABC
文件夹中,所以代码中所有的依赖路径都是 ../ABC/..
,这个时候在本地跑是没有问题的。
但是在服务器上面,其实依赖的文件有一部分是存在 abc
中的。因为路径都是指向 ABC
,而 ABC
文件中并没有这些文件(文件在 abc
中),这个时候就会报路径错误。
这样的错误是如何产生的?
发生这样的问题我也是很好奇,于是我翻到了这个文件夹当时的 commit 记录,发现当时是两个人一起来开发一个任务,于是大家一起商量好的文件夹的名称,却因为没有规范名称的大小写所以出现了问题。
例如 A 创建了 ABC
然后代码里的依赖路径为 ../ABC/..
,B 创建了 abc
,依赖路径为 ../abc/..
。因为上传到服务端之后文件夹都是会存在的,并不会合并,所以对于当时的情况来说,并不会发生路径错误。so,这个坑就这样产生了。
这个错误引发的问题
这个坑对于以后的开发人员来说就说一个很大的坑了,不,应该说是巨坑、天坑!
这一段可能会很绕,仔细看:因为代码再 pull 到本地之后,两个文件夹就会合并成一个,比如这个时候合并成了 ABC
,那么这个时候依赖 ../abc/..
的功能就爆炸了,这个时候 Debug 就发现,咦,这里怎么会有依赖 ../abc/..
的路径,怪不得会有问题,赶紧改成 ../ABC/..
,嗯,这个时候代码 OK 了,可以跑起来了。但是!当代码再次 push 到了服务器上的时候,问题又来了,因为依赖 abc
文件夹的代码被改成了 ../ABC/..
啊,但是文件其实还是在 abc
中的啊,所以服务器上的代码又爆炸了。
这个时候接手代码人的内心:wtf???让我死不好吗。
解决的方法
把服务器上的两个文件夹先删掉一个,然后重新上传一下代码,确保只有一个文件夹。
如何避免这样的问题:
- 确定好文件名的规范,比如使用驼峰,或者全部小写等等
- 两个分支同时创建文件夹的时候名字大小写不要搞错了,不然合并的时候就是两个文件夹
拓展
Git 为什么是默认不区分大小写?
其实根据上面的一些分析,我觉得有一定原因是为了兼容 Widnows 和 macOS 的,因为这两个系统默认是不区分大小写的。
即使 Git 支持了区分大小写,可以有两个大小写不同但是名称相同的文件夹,但是 Windows 和 macOS 不能显示,那岂不是很尴尬。