将文件名从小写更改为大写。使用 git config --local core.ignorecase false,但两个文件同名但大小写不同

Amb*_*ber 4 git gitlab


我将文件名从小写更改为大写,然后尝试合并。

失败了,所以我补充一下

git config --local core.ignorecase false
Run Code Online (Sandbox Code Playgroud)

然后就变成了gitlab中同名的两个文件(一个大写,一个小写)。

如果我克隆该项目,它将全部小写。

我尝试在gitlab中删除小写的,但是如果我再次拉取,文件将是空的。

不知道如何修复它。

tor*_*rek 5

解决此问题的最佳方法是使用小写和大写不同的系统。例如,如果您无法使用 Windows,请启动 WSL 或使用 VirtualBox 或类似工具来创建 Linux 系统,将存储库克隆到其他操作系统中,修复问题,提交并推送新的提交。(然后您可以关闭 WSL 或 VirtualBox 实例。)

\n

长长的:发生了什么事

\n

你滥用了core.ignoreCase:你对 Git 撒谎,Git 得到了报复。

\n

这里有一个关键概念有点棘手,不幸的是,很多 Git 文档都不清楚,很多 Git 教程和介绍材料都不是很好,甚至非常糟糕这可能会引导你走上这里的花园小路。。以下是您需要了解的内容:

\n
    \n
  • 任何给定的 Git 存储库都会存储提交(以及名称,例如分支名称和标记名称,可帮助您和 Git找到提交,但在这里我们将专门关注提交)。

    \n
  • \n
  • 提交存储文件\xe2\x80\x94,但它们以一种特殊、奇怪、Git 独有的格式进行。提交不存储目录(文件夹),仅存储文件;每个文件都有一个名称,并且该名称由任意字节序列组成,只有一些限制:具体来说,该名称不能以(正)斜杠开头,并且不能有两个相邻的正斜杠,并且不能包含 NUL 字节(b\'\\0\'Python 风格编码中的a )。两个不同的字节序列代表不同的文件名,因此path/to/filepath/TO/FILE是两个不同的文件;path/TO/file第三个不同的文件,依此类推。请注意,这里没有文件夹名称:path/to/file是一个文件名,它只是在您完成实际工作时碰巧包含像文件夹名称一样的东西,而不是在 Git 中闲逛。

    \n
  • \n
  • 签出提交(使用git checkoutgit switch),Git 会将提交中的文件提取到 Git 所谓的工作树中中。这里的文件将是普通计算机上的普通文件,以便普通程序可以用它们做普通的事情。

    \n
  • \n
  • Git 实际上从 Git 所谓的索引暂存区域(或者有时称为缓存)构建新的提交。这个东西保存文件,其格式与 Git 用于提交的格式相同,因此索引中的文件具有区分大小写的长名称 ( ) ,无论您的系统是否区分大小写。path/to/file

    \n
  • \n
\n

因此,存储提交(存储文件)的 Git 存储库可以包含具有两个仅大小写不同的文件的提交,例如readme.mdREADME.md。这始终是正确的:您在 Git 中设置的任何设置都无法阻止这一点。

\n

大多数操作系统和/或文件系统对文件的显示方式都有限制。此处并非所有操作系统和文件系统都相同:特别是 Windows,在将长path/to/file.ext字符串分解为组件pathto、 和file.ext(然后将其表达为path\\to\\file.ext稍后!)后,禁止将该file部分命名为aux。尝试为 C 或 C++ 程序创建一个auxor文件,或者为 Python 程序创建一个文件,然后看看会发生什么。这在 Linux 和 macOS 上运行良好,但在 Windows 上则不然。1aux.haux.py

\n

默认情况下,在大多数文件系统中,Windows 和 macOS 都会保留新创建的文件或文件夹大小写,因此,如果您创建一个名为 的新文件README.md,它实际上名为README.md. 但从那时起,两个系统都会将创建或使用readme.md(全部小写)的尝试视为使用现有README.md文件的请求。也就是说,这些操作系统和/或文件系统 会忽略您使用的大小写,而支持某些现有文件或文件夹的大小写。

\n

这意味着,如果您有一个包含 README.md readme.md的提交,则检查此提交只能提取这两个文件之一。Git首先创建的文件名将是您在工作树中看到的名称。具体来说,GitREADME.md首先创建。第二文件将简单地覆盖第一个文件,只留下一个名为 的文件README.md,其中包含readme.md文件的内容

\n

(作为一个配置变量,忽略core.ignoreCase大小写,以便您可以设置core.ignorecasecore.IGNORECASE如果您愿意)的目的是告诉 Git 系统的行为方式。更改它不会改变系统的行为方式!这是一个描述性设置,而不是规定性设置。

\n

临时更改设置来欺骗 Git偶尔(尽管很少)有用。在 Git 完美的理想世界中,您永远不必这样做,但那个世界根本不存在(也永远不会)存在。所以你会发现偶尔的 StackOverflow 答案会让你暂时改变core.ignoreCase并做一些事情。 完成后请务必将其更改回来,因为 Git相信该设置。如果设置错误,Git 将出现异常行为。说“改变它”的答案是故意对 Git 撒谎,让它以一种方式行为不当,结果证明这一次是有用的,也许会再次有用,只要你有相同版本的 Git 和相同的版本。版本的 Windows或者它仍然碰巧以这种方式工作。

\n

特别是,当您关闭core.ignoreCase(将其设置为false)时,Git 认为操作系统可以保存某些文件的大写和小写变体。您通常会这样做来操作 Git 的索引git add file.ext现在运行将添加小写版本,运行git add FILE.EXT将添加大写版本(运行git add FiLe.eXt将添加混合大小写的第三个版本)。运行git rm --cached将使您从 Git 索引中删除任何一种特定的案例版本,同时相信该案例很重要。完成此操作后,您应该恢复设置,core.ignoreCase以便它描述您的系统的实际工作方式。

\n

您可以使用git ls-files --stage(或者甚至不使用--stage--stage只是使输出更加详细)来查看Git 索引中现在有哪些文件。请注意,此命令会生成每个文件的完整列表,在大型存储库中,该列表可能会很长,因此您可能需要使用 bash 样式的重定向:

\n
$ git ls-files --stage > output.tmp\n
Run Code Online (Sandbox Code Playgroud)\n

然后使用文件查看器output.tmp,然后删除output.tmp在完成后将其删除。

\n
\n

1虽然 macOS 避免了一些 Windows 问题,但大小写折叠功能仍然有效,除非您创建区分大小写的文件系统。制作一个可安装的很容易.dmg,如果您使用 Mac,那么最好有一个这样的文件,以便您可以处理在 Linux 上制作的 Git 存储库。

\n

请注意,macOS 对于某些 Unicode 序列有一个相当不同的问题,这在 macOS 中与aux.hWindows 上的问题一样难以克服。因此,您可能仍然需要可以在 Mac 上运行的 Linux。

\n