4

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

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

从 git-config 文档:

内部变量,它支持各种变通方法,以使 Git 在不区分大小写的文件系统上更好地工作,例如 APFS、HFS+、FAT、NTFS 等。例如,如果目录列表在 Git 需要“Makefile”时找到“makefile”,则 Git将假定它确实是同一个文件,并继续将其记住为“Makefile”。

…</p>

Git 依赖于为您的操作系统和文件系统正确配置此变量。修改此值可能会导致意外行为。

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

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

我读过人们说你绝对应该这样做的帖子,以及一些完全相反的帖子。

4

1 回答 1

4

据我所知,设置 ignorecase = true 将使如果 git 检测到相同的文件名但大小写不同,它将更改 git 索引中的名称以匹配文件系统上的名称(即如果 Windows 有foo.js并且 git checkout/pull 有Foo.js,它将假定这foo.js是正确的并且 git 将使用该大小写)。

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

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

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

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

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

于 2019-10-01T21:39:23.207 回答