git 大小写问题

Git ignorecase issue

Posted by Bryan on August 31, 2019

背景介绍

最近在项目中遇到一个比较奇怪的问题,在整理了前端的 React 编码规范 之后,在项目组内沟通之后,决定前端采纳此编码规范,对于旧的代码暂时不大范围的改造,新的代码按照规范来写。某一次对某个组件目录 listContainer 进行了比较多的重构,此时将组件目录名从驼峰命名修改为帕斯卡命名方式,即将目录的首字母修改为大写,改为 ListContainer, 修改之后本地测试良好,于是将修改提交上线。

隔一段时间之后,有同事反馈,他从 git 上完整 clone 项目,出现了异常,检查后发现 listContainer 中代码部分出现在 listContainer 目录中,部分出现在新目录 ListContainer 中,我同步了线上的代码,发现我本地的代码是完全正常的,只有一个 ListContainer 目录,执行也完全正常。这就很诡异了。

问题定位

定位这个问题其实比较清晰,按照下面的步骤进行了定位:

  1. 首先确认远端的代码的正确性,查看了一下,代码是不正确的,同时出现了 listContainerListContainer 目录;
  2. 接下来的问题就比较奇怪,本地与远端代码不一致,但是拉取远端代码后,本地代码依旧没有改变。而尝试将本地的代码推送至远端,远端的代码也没有任何变化。看起来在 git 认为本地和远端的代码是一样的,而这两者的主要区别是目录的大小写不同;
  3. 按照上面的思路,google 一下就可以确定问题了,git 在 mac 下面默认是大小写不敏感的,因此本地的修改如果只有目录名变为大写,那么 git 会认为没有修改,而如果此目录中有文件修改了内容,此时 git 同步内容时会按照此文件新的路径同步至远端。因此就出现了之前的问题。

git 大小写问题

git 的默认大小写不敏感是一个比较奇怪的特性,从产品给人最少的意料之外的情况的角度来看,这个特性默认设置为不敏感是值得商榷的。简单搜索一下就会发现,有各路程序员都掉到这个坑里了。

这个问题的处理比较简单,增加两个 commit,第一个 commit 将目录名修改为完全不同的名字,第二个 commit 将名字改回来即可。

一个长期来看避免踩坑的方法是配置大小写敏感,可以执行 git config --global core.ignorecase false 即可。