Git-windows 区分大小写的文件名未正确处理
我们在 unix 中有 git bare 存储库,其中包含具有相同名称的文件,仅大小写不同。
示例:
GRANT.sql
grant.sql
当我们将裸存储库从 unix 克隆到 windows 环境中时,git status 会检测到文件已修改。工作树仅加载 grant.sql,但 git status 会比较 grant.sql 和 GRANT.sql 并显示工作树中修改的文件。
我尝试使用 core.ignorecase false 但结果是相同的。
有什么办法可以解决这个问题吗?
We have the git bare repository in unix that has files with same name that differs only in cases.
Example:
GRANT.sql
grant.sql
When we clone the bare repository from unix in to a windows box, git status detects the file as modified. The working tree is loaded only with grant.sql, but git status compares grant.sql and GRANT.sql and shows the file as modified in the working tree.
I tried using the core.ignorecase false but the result is the same.
Is there any way to fix this issue?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
Windows 不区分大小写(更准确地说,保留大小写)。根本不可能存在两个名称仅大小写不同的文件:两个仅大小写不同的文件名是相同的文件名。时期。
因此,Git 会遍历存储库,一个接一个地检查文件,直到找到两个有问题的文件中的第一个。 Git 对其进行检查,然后进一步处理其业务,直到找到第二个文件。 Git 再次检查它。由于从 Windows 的角度来看,文件名与第一个文件名相同,因此第一个文件只是被第二个文件覆盖。现在,Git 认为第一个文件已更改为与第二个文件具有相同的内容。
请注意,这与 Git 无关:如果您有 tarball、zip 文件或 Subversion 存储库,也会发生完全相同的情况。
如果您想在多个不同平台上进行开发,您必须尊重这些平台的限制,并且必须将自己限制在您支持的所有平台的最低公分母上。 Windows 支持 ADS,Linux 不支持。 OSX 支持资源分叉,Windows 不支持。 BSD 支持区分大小写,Windows 不支持。所以,你不能使用其中任何一个。事情就是这样。
core.ignorecase
不会在这里为您提供帮助,因为它恰好处理相反的问题。Windows is case-insensitive (more precisely, case-preserving). There is simply no possible way for two files to exist whose names only differ in case: two filenames which differ only in case are the same filename. Period.
So, Git is walking the repository, checking out one file after the other, until it hits the first one of the two problem files. Git checks it out, then goes further about its business until it hits the second file. Again, Git checks it out. Since from Windows' point of view the filename is the same as the first one, the first file simply gets overwritten with the second one. Which now makes Git think that the first file was changed to have the same content as the second one.
Note that this has nothing to do with Git: exactly the same would happen if you had a tarball, a zipfile or a Subversion repository.
If you want to do development on multiple different platforms, you have to respect the restrictions of those platforms and you have to confine yourself to the lowest common denominator of all the platforms you support. Windows supports ADS, Linux doesn't. OSX supports resource forks, Windows doesn't. BSD supports case-sensitivity, Windows doesn't. So, you can't use any of those. That's just the way it is.
core.ignorecase
isn't going to help you here, because that handles exactly the opposite problem.我刚刚遇到了类似的问题。就我而言,两个名称相似但大小写不同的文件位于与 Windows 克隆不相关的子目录中。 Git 1.7 有一个稀疏签出 允许您从工作副本中排除某些文件的功能。排除此目录:
此后,
unwanted_dir/
子目录从我的工作副本中完全消失,Git 继续正常处理其余文件。如果您的
GRANT.sql
和grant.sql
在 Windows 克隆上不相关,那么您可以将它们的名称添加到.git/info/sparse-checkout< /code> 专门排除这些文件。
I just encountered a similar problem. In my case, the two files with similar names differing only in case were in a subdirectory that wasn't relevant on the Windows clone. Git 1.7 has a sparse checkout feature that lets you exclude certain files from a working copy. To exclude this directory:
After this, the
unwanted_dir/
subdirectory was completely gone from my working copy and Git continues to work with the rest of the files as normal.If your
GRANT.sql
andgrant.sql
are not relevant on the Windows clone, then you can add their names to.git/info/sparse-checkout
to exclude those files specifically.我不确定这是否可能。 Git 的ignorecase 处理单个文件的大小写差异。它无法解决 Windows 无法在一个目录中拥有两个仅大小写不同的文件名的问题。
FWIW,拥有两个相同的文件名但就其情况而言是一个非常糟糕的主意,即使在 Unix 上也是如此。
I'm not sure this is even possible. Git's ignorecase handles discrepancies in the case of the one file. It won't work around Window's inability to have two filenames in the one directory that differ only by case.
FWIW, having two identical filenames but for their case is a really bad idea, even on Unix.
如果您想让存储库对不区分大小写的文件系统友好,您可以添加一个提交挂钩,以防止您签入冲突文件。
此脚本需要 git version >= 1.7.7,因为它使用 stash -u,以避免在未跟踪的文件上失败。
If you want to keep your repository friendly to non-case sensitive file systems, you can add a commit hook that prevents you to check in clashing files.
This script requires git version >= 1.7.7, because it uses stash -u, to avoid failing on untracked files.
Cygwin 在处理文件名中的区分大小写和有趣字符方面比 MSys 好得多。
更改此注册表项以在 Windows 中启用区分大小写:
HKLM\System\CurrentControlSet\Control\Session Manager\Kernel\ObCaseInsensitive=0
请参阅 此处了解 Cygwin 如何支持区分大小写的一些注意事项。
Cygwin handles case sensitivity and funny characters in filenames much better than MSys.
Change this registry key to enable case sensitivity in Windows:
HKLM\System\CurrentControlSet\Control\Session Manager\Kernel\ObCaseInsensitive=0
See here for some caveats in how case sensitivity is supported in Cygwin.
实际解决问题的最简单方法是重命名其中一个文件,这样它们就不会在 Windows 或 OS X 等不区分大小写的文件系统上发生冲突。
在 Linux/Unix 系统提交之后,您可以最轻松地解决这个问题问题是,拉动后,Windows 上一切都会好起来。为了防止出现此问题,您需要添加一个类似于 djjeck 建议的提交钩子。
Windows 上的症状非常令人困惑,包括:
由于这两个文件不能在不区分大小写的平台上共存,因此您必须更改其中一个文件名以避免出现麻烦。
The simplest way to actually fix the issue is to rename one of the files so that they won't conflict on a case-insensitive file system like Windows or OS X.
Following a commit from the Linux/Unix system where you can most easily address the problem everything will be fine on Windows after a pull. To prevent this problem from occurring you would need to add a commit hook similar to what djjeck suggested.
The symptoms on Windows for this are very confusing and include:
Since both files can not coexist on a case insensitive platform you have to change one of the file names to avoid the trouble.
另一种简单的方法可以避免 git read-tree --reset -u HEAD
Another simple approach which can avoid
git read-tree --reset -u HEAD