将 git config core.ignorecase 设置为 false 是个好主意吗?

Is it a good idea to set git config core.ignorecase to false?

我的团队目前管理一个跨多个文件系统的 git 存储库。我们大多数人使用 Windows,但我们中的一些人使用 Linux。另外,我们将生产代码部署在 Linux 服务器上。这导致了我们代码库中文件名大小写的多个问题(即当文件实际上是 foo.js 时导入 Foo.js)。最近,我完成了项目文件夹的清理工作,主要包括重新组织我们的目录并将我们的 directories/files 重命名为通用命名标准。很多文件名更改都会更改文件的大小写(例如 foo.js -> Foo.js)。

当我进行这些更改时,我并不完全了解 git 在区分大小写和不区分大小写的文件系统上如何以不同方式处理文件名,这导致了很多奇怪的错误。我在研究这个时遇到的一件事是 .gitconfig 中的 ignorecase 值。

来自 git-config 文档:

Internal variable which enables various workarounds to enable Git to work better on filesystems that are not case sensitive, like APFS, HFS+, FAT, NTFS, etc. For example, if a directory listing finds "makefile" when Git expects "Makefile", Git will assume it is really the same file, and continue to remember it as "Makefile".

Git relies on the proper configuration of this variable for your operating and file system. Modifying this value may result in unexpected behavior.

根据我的理解,设置 ignorecase = true 将使得如果 git 检测到相同的文件名但大小写不同,它将更改文件中的名称git 索引以匹配文件系统上的内容(即如果 Windows 有 foo.js 和 git checkout/pull 有 Foo.js,它将假设foo.js 是正确的,git 将使用那个大小写)。我担心的是,如果我推送到远程并且我们的部署服务器接收到更改,将会发生什么。然后它将尝试导入不存在的 Foo.js 并出错。

但是,通过设置ignorecase = false,那么git应该能够检测到文件名有差异并正确替换文件。这是正确的吗,我是否应该让我的团队将此值设置为 false,因为我们跨不同的文件系统工作?

我看过有人说你绝对应该这样做的帖子,还有一些帖子的说法恰恰相反。

From what I'm able to understand from this, setting ignorecase = true will make it so that if git detects the same file name but with different casing, it will change the name in the git index to match what is on the filesystem (i.e. if Windows has foo.js and a git checkout/pull has Foo.js, it will assume that foo.js is correct and git will use that casing).

不,这是倒退的:文档指出,如果索引当前包含 Foo.js,并且工作树出于某种原因具有 foo.js,Git 将假设foo.js 实际上是 Foo.js 并将 Foo.js 放入下一次提交。然而,将 core.ignorecase 设置为 false,Git 完全相信工作树:git add . 将删除大写名称(和内容)并使用小写名称 foo.js 根据工作树中的副本在索引中安装新副本。

(要查看索引中的内容,请使用 git ls-files --stage,或省略 --stage 以仅获取文件名。请注意,这会转储整个索引内容!将路径参数添加到 select 特定文件,例如 git ls-files "[Ff]oo.js",只查找那些文件。在类 Unix shell 中需要引号,例如 bash,以保持 shell 从这里解释元字符 [Ff]。shell 将删除引号。在其他 Windows-specific 命令行解释器中使用什么,我不确定。)

一般来说,您不应该更改 core.ignorecase。如果要重命名文件,最直接的方法是使用 git mv(同时调整索引和工作树)。如果你只想改变大小写,你可以 git mv 两次:

git mv foo.js temporary-name
git mv temporary-name Foo.js

现在您 Foo.js 在索引和工作树中都有初始资本。某些版本的 Git 可以在没有中间临时名称的情况下处理这个问题,但是当您使用中间名称时,所有版本都会做正确的事情。