[TOC] #### 1. 场景描述 --- 作为一个使用 git 作为版本控制的程序员,相信各位都遇到过这种问题,文件名或目录名的大小写整错了 **场景描述** 比如:想要创建一个文件 `User.php`,但是文件名打成了 `user.php`,并且已将 `user.php` 提交到了版本库 然后,你应该会将错误的 `user.php` 修改为正确 `User.php`,但是发现 git 没有监听到文件发生变化 **问题原因** 这是因为 git 默认不区分文件名的大小写,也就是对大小写不敏感,所以此时 git 并不认为文件发生变化了 **尝试解决** 先尝试使用 `git mv` 命令从工作区和暂存区重命名文件,发现是不行的,继续尝试其他方法 ```plaintext $ git mv user.php User.php fatal: destination exists, source=user.php, destination=User.php ``` **我的解决办法** 之前我遇到这种问题,会先修改其名称(不仅仅修改大小写),提交到版本库,然后再修改为正确的名称,再次提交 比如:将 `user.php` 修改为 `user1.php` 后提交到版本库,然后再修改为 `User.php`,再提交到版本库 **利弊分析** 但是,这种办法肯定不好的,为了解决这个问题就多了两个提交记录,对于自己要求高的开发者会追求更好的方式 其实,git 提供了严格区分大小写的配置项,接下来我们学习一下这个配置,当修改了名称的大小写,让 git 自己去发现 #### 2. 配置命令 --- 查看当前是否忽略大小写配置,输出结果:true(忽略大小写,默认配置)、false(已经严格区分大小写) ```bash git config --get core.ignorecase ``` 全局设置,将忽略大小写关闭,也就是开启大小写敏感,从而能够正确识别文件名大小写的更改 ```bash git config --global core.ignorecase false ``` 不过,有时从远程仓库拉取到本地时,当前项目的 git 配置可能默认就是忽略大小写(经测试 gitee 是这样的) clone 项目后,查看本地仓库配置文件内容,或者查看本地仓库配置都可以证实 ```bash # 查看本地仓库配置文件内容 cat .git/config # 查看本地仓库配置中的忽略大小写配置 git config --local --list | grep ignorecase ``` 因为项目配置优先级高于全局配置,所以此时全局配置开启大小写敏感已经失效,需要手动设置当前项目开启大小写敏感 ```bash git config core.ignorecase false ``` #### 3. 流程分析 --- 开启大小写敏感后,修改文件名,git 能监听到文件变化了,直接提交是不是就可以将文件重命名成功了呢 ? 将 user.php 重命名为 User.php,查看状态可以发现 + user.php 没有提示被删除,所以它还在被 git 管理追踪 + User.php 是一个没有追踪的文件,需要将它提交到暂存区 ```plaintext On branch master Your branch is up to date with 'origin/master'. Untracked files: (use "git add <file>..." to include in what will be committed) User.php nothing added to commit but untracked files present (use "git add" to track) ``` 如果直接将 User.php 提交到版本库,会怎么样 ?你会发现远程库既有 user.php,又有 User.php(此时你是不是很无语) ```bash git add User.php git commit -m '将 user.php 修改为 User.php' git push ``` 因为远程库有两个相同名称的文件(只是大小写不同),别人 clone 仓库时,能拉取成功,但是会有以下提示 ```plaintext 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: 'User.php' 'user.php' ``` 所以,我们需要将远程库的无用的 user.php 删除掉。然后,别人重新 clone 就可以得到正确的 User.php 了 ```bash git rm --cached user.php git commit -m '删除暂存区中的 user.php' git push ``` #### 4. 最佳实践 --- 首先,关闭忽略大小写,也就是开启大小写敏感,修改文件名称时让 git 可以追踪的到 ```bash git config core.ignorecase false ``` 手动修改文件名称,然后从暂存区删除旧文件,将新文件提交到暂存区 ```bash git rm --cached user.php git add User.php ``` 此时查看状态,也可以发现当前确实是一个重命名的操作 ```plaintext On branch master Your branch is up to date with 'origin/master'. Changes to be committed: (use "git restore --staged <file>..." to unstage) renamed: user.php -> User.php ``` 然后正常提交并推送到远程库即可 ```bash git commit -m 'renamed: user.php -> User.php' git push ```