git忽略大小写的问题,以及远程仓库同时存在大小写不同的文件的解决方案

写在前面

在项目开发的时候,一个99%的人都会遇到的问题:就是git作为版本控制工具。 文件名、文件大小写的问题。 因为我对git的理解不够深入导致花费了不少时间来排查,同时也体会到好的规范比好的技术其实更重要。

搭建环境

  1. 新建gitee仓库

  2. 执行创建git仓库的命令

搭建测试案例

  1. 新建一个文件夹testfolder,作为测试文件夹,并且里面有一个innertestfile.txt文件,里面有内容,作为测试文件
  2. 新建一个文件testfile.txt,并且添加内容,作为测试文件 查看git status,
  1. 将testfile.txt添加到git仓库中 执行add . 命令,将testfile.txt添加到git仓库中 执行commit -m "add testfile.txt" 命令,将testfile.txt提交到git仓库中 此时远程仓库的情况:

问题复现

  1. 现在修改testfile.txt文件,将testfile.txt修改为Testfile.txt,然后执行git status命令,发现git没有检测到文件的变化,因为git默认忽略大小写,所以git认为Testfile.txt和testfile.txt是同一个文件,所以没有检测到变化。

2. 现在在更改了文件名的情况下,修改文件的内容。

3. 然后提交,发现提交成功,但是远程仓库的文件名没有变化,还是testfile.txt,而本地仓库的文件名已经变成了Testfile.txt。

  1. 如果执行 git config core.ignorecase false,设置Git的规则为区分大小写(大小写敏感),此时执行git status,显示有一个新的文件Testfile.txt
  1. 把这个新增的文件提交到远程仓库,执行git add .,然后执行git commit -m "add Testfile.txt",然后执行git push,发现远程存在两个文件,一个是testfile.txt,一个是Testfile.txt。
  1. 此时如果同事现在拉取这个仓库,因为操作系统(mac和windows)是不支持文件名大小写区分的,所以他会发现,远程仓库有两个文件,一个是testfile.txt,一个是Testfile.txt,他会很懵逼,不知道该用哪个文件,所以这里我的mac系统会选择删除Testfile.txt,保留testfile.txt。
  1. 但是如果是linux操作系统,就会保留着两个文件,如下:

这里就遇到了两个问题:

  1. git 在团队开发中的规范问题,如果团队中有人修改了文件名的大小写,应该如何正确修改。
  2. git远程仓库的两个文件,在同事下次拉取仓库的时候,会报错,存在风险;需要删除远程仓库中不需要的文件。(这个问题本来可以在修改文件名的时候就解决,但是因为之前没有意识到,所以导致这个问题)

解决方法

对于本地的文件需要修改文件名的大小写

  1. 执行git config core.ignorecase false命令,将git的忽略大小写功能禁用。
  2. 对于需要修改文件名的大小写的情况,需要执行git mv testfolder/innertestfile.txt testfolder/Innertestfile.txt,将文件名的大小写修改正确,这里把testfolder目录下的innertestfile.txt修改为Innertestfile.txt。
  3. 这时候,执行git status命令,发现git已经检测到文件的变化,是一个renamed的变化,并且存入了暂存区。
  1. 这时候git push,发现远程仓库的文件名已经变成了Innertestfile.txt,而不是innertestfile.txt。

对于本地的文件需要修改目录名的大小写

这里把根目录下的testfolder目录改成了Testfolder目录,和修改文件名的大小写有点区别。

bash 复制代码
# 将本地的 test 目录删掉,并生成一个新的目录 tempfolder
$ git mv testfolder tempfolder

# 将 tempfolder 目录改成 Testfolder 目录。此时,项目中只会存在 Testfolder 目录,不会存在 testfolder 目录。目标达成。
$ git mv tempfolder Testfolder

执行git status命令,发现在暂存区有reanmed类型的修改,然后直接push到远程,就可以了。

对于远程已经有了大小写不同的文件,如何解决

  1. 直接在文件夹中删除大小写不同的文件,然后重新添加正确的文件名,然后提交到远程仓库,例如这里需要删除远程仓库的A和a文件中的a文件。
  2. 使用git ls-files命令查看所有已经被 Git 跟踪的文件;这里可以看到A和a文件都被跟踪了。
  3. 使用git rm a命令,将文件a的跟踪从 Git 仓库中删除。
    1. 执行完这个命令后可能会删除本地的A文件,这是你之前已经执行过git rm a命令,所以本地已经没有a文件了,所以会删除A文件。
    2. 可以使用git restore A命令,将A文件恢复到最近一次提交的状态。
  4. 紧接着commit,push后,远程仓库的a文件就删除了,同时两个仓库都是只有A文件。

对于目录:

  1. 执行git rm -r a命令,将目录a的跟踪从 Git 仓库中删除。
  2. 紧接着commit,push后,远程仓库的a目录就删除了,同时两个仓库都是只有A目录。

最后

关于是否区分大小写的补充说明

我们知道:针对文件/文件夹,Windows系统Mac系统通常是不区分大小写的;Linux系统是区分大小写的; Git默认是不区分大小写的,也可以通过改配置项,改为区分大小写。

不分区大小写,也有它的好处,比如:文件夹/文件的路径,很多时候就代表了网站地址、页面url的路径。而网站地址也是不区分大小写的,这是很关键的原因之一。

是否需要开启git的忽略大小写功能的探讨

执行git config --global core.ignorecase false,全局设置 大小写敏感。这样下次修改了文件的时候,就会有感知,开发者就能看到修改。

在开发中,开发者对修改的文件或者目录在git status中文件名大小写修改没有感知,是很危险的,所以推荐使用命令git config core.ignorecase false修改配置。并且要切记,在修改完了之后,要记得把原来的文件使用git rm <原文件>命令删除掉。

撤销未暂存的更改的命令

如果您想撤销对 testfile.txt 的删除操作(这个文件还没有被暂存),您可以使用以下命令:

bash 复制代码
git restore testfile.txt

这个命令会将 testfile.txt 恢复到最后一次提交的状态,撤销您在工作目录中对它的删除。

查看所有跟踪的文件命令

您可以使用 git ls-files 命令来列出所有已经被 Git 跟踪的文件:

bash 复制代码
git ls-files

这个命令会列出仓库中所有当前被跟踪的文件。

git mv命令

  1. git mv 就相当于运行了下面三条命令:
bash 复制代码
$ mv README.md README
$ git rm README.md
$ git add README

总结

  1. 良好的开发规范,可以避免很多不必要的麻烦。
  2. 推荐在一个仓库修改配置git config core.ignorecase false的值,这样,在这个仓库中,文件名的大小写是敏感的,可以避免修改文件大小写git监测不到的问题。
  3. 如果需要重命名一个文件或者目录的大小写,推荐使用git mv <旧文件名> <新文件名>命令,而不是直接在操作系统提供的命令来删除文件;对于目录,可以加上-r参数。(这句话推荐加入团队的开发规范中)

参考

代码仓库地址:

gitee.com/chouvel/git...

参考:

解决 Git 不区分大小写导致的文件冲突问题

Git-基础-记录每次更新到仓库

相关推荐
挽 阳2 小时前
vscode 识别git目录
ide·git·vscode
创实信息7 小时前
GitHub企业版:AWS CodeCommit迁移的最佳路径与技术优势
git·ci/cd·github·aws·github企业版·aws codecommit
W21559 小时前
git的使用及其原理
git
Cachel wood10 小时前
Vue.js前端框架教程11:Vue监听器watch和watchEffect
前端·javascript·vue.js·git·ui·前端框架·ecmascript
海绵宝龙11 小时前
git stash 的文件如何找回
git
Zhu_S W13 小时前
常用git命令大全
git
XWXnb620 小时前
Git使用步骤
git
YG·玉方20 小时前
GIT命令使用手册(详细&实用版)
git
八月五1 天前
Git连接远程仓库(超详细)
git