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-基础-记录每次更新到仓库

相关推荐
海鸥8119 小时前
in argocd ‘/tmp/_argocd-repo/../.git/index.lock‘: No space left on
git·argocd
尔嵘20 小时前
git操作
大数据·git·elasticsearch
大柏怎么被偷了1 天前
【Git】企业级开发模型
git
Garfield20051 天前
Git 分支拓扑实践
git·拓扑
DKNG1 天前
【Windows Host】 hosts配置增加访问github流畅度
人工智能·git·github
一个很帅的帅哥1 天前
git命令大全
大数据·git·elasticsearch
凯子坚持 c1 天前
Git 远程仓库操作与深度进阶指南
git
勇敢牛牛_1 天前
RustRover 2025.3 在WSL中GIT操作十分缓慢的问题
git·rust·rustrover
编程小白gogogo1 天前
创建git仓库并推送苍穹外卖初始项目
git
cat_milk1 天前
【git】git的基础使用二
git