2010-03-27 60 views
31

在unix中,我们拥有git裸存储库,它具有仅在不同情况下具有不同名称的文件。Git-windows区分大小写的文件名无法正确处理

实施例:

GRANT.sql 
grant.sql 

当我们克隆从UNIX纯仓库中的窗户框,git的状态检测该文件作为修改。工作树只加载grant.sql,但git状态会比较grant.sql和GRANT.sql,并显示在工作树中修改的文件。

我试过使用core.ignorecase false但结果是一样的。

有什么办法解决这个问题吗?

+0

真棒问题和格雷格的答案只是岩石! – Hazok 2011-05-20 20:07:26

+0

当您在Windows上的不同分支中创建具有不同外壳的文件时,也会发生这种情况。 – Thomas 2017-03-15 15:35:39

回答

4

我不确定这甚至是可能的。在一个文件的情况下,Git的ignorecase处理差异。它无法在Window的无法在一个目录中有两个文件名的情况下区分大小写。

FWIW,具有两个相同的文件名,但对于他们的情况是一个非常糟糕的主意,即使在Unix上。

+0

如果只有Linux内核的开发人员都同意你的意见...... – 2013-02-06 12:42:24

36

Windows不区分大小写(更精确地说,是病例保留)。两种文件的存在根本没有可能的方式,其名称仅在大小写不同的情况下存在:两种仅在大小写不同的文件名是相同的文件名。期。

因此,Git正在存储库中检查一个文件,直到遇到两个问题文件中的第一个文件。 Git检查出来,然后进一步了解它的业务,直到它遇到第二个文件。再次,Git检查出来。由于从Windows的角度来看,文件名与第一个文件名相同,第一个文件只是被第二个文件覆盖。现在让Git认为第一个文件被更改为与第二个文件具有相同的内容。

请注意,这与Git无关:如果您有tarball,zipfile或Subversion存储库,则会发生同样的情况。

如果您想在多个不同的平台上进行开发,您必须尊重这些平台的限制,并且您必须将自己局限于您支持的所有平台的最低公分母。 Windows支持ADS,Linux不支持。 OSX支持资源分叉,Windows不支持。 BSD支持区分大小写,Windows不支持。所以,你不能使用任何这些。就是那样子。

core.ignorecase不会帮你在这里,因为那句柄正好对着对面的问题。

+2

+1的详细解释 – cctan 2012-02-23 08:46:46

+1

修复这并不意味着它只是工作。 解决这个问题意味着你将疯狂的行为转化为明确的错误。 – jrodman 2016-01-30 18:37:25

+1

绝对有两种文件的存在方式,其名称只有大小写不同,但它需要注册表更改。 Cygwin做到了,但我不知道msys是否可以(需要将特殊标志传递给Win32 API):https://cygwin.com/cygwin-ug-net/using-specialnames.html – Matt 2016-03-16 20:50:33

32

我刚遇到类似的问题。在我的情况下,名称相似的两个文件仅在大小写不同的子目录中与Windows克隆无关。 Git 1.7有一个sparse checkout功能,可让您从工作副本中排除某些文件。要排除此目录:

git config core.sparsecheckout true 
echo '*' >.git/info/sparse-checkout 
echo '!unwanted_dir/' >>.git/info/sparse-checkout 
git read-tree --reset -u HEAD 

在此之后,unwanted_dir/子目录已完全从我的工作拷贝不见了和Git继续与文件的其他部分正常工作。

如果您的GRANT.sqlgrant.sql与Windows克隆无关,则可以将它们的名称添加到.git/info/sparse-checkout以明确排除这些文件。

+1

This答案太棒了,并且对于文件名太长的问题也适用。感谢您解除我所遇到的头痛!几个月前给+1。 – Hazok 2011-05-20 19:58:19

+1

伟大的解决方案!我需要设置为'core.sparseCheckout'才能使之起作用 – 2011-09-28 22:50:09

+1

该提示非常有帮助!真棒! – Fei 2015-09-02 05:49:59

1

Cygwin比MSys更好地处理文件名中的大小写敏感和有趣的字符。

更改此注册表项,以在Windows中启用区分大小写:

HKLM \系统\ CurrentControlSet \控制\会话管理器\核心\则会出现此问题= 0

here在一些注意事项如何区分大小写支持在Cygwin。

2

如果您想让您的存储库对不区分大小写的文件系统保持友好,则可以添加一个提交挂钩,以防止您检入冲突文件。

#!/bin/bash 

# Save current state 
git stash -u -q --keep-index || exit 1 

# Get the list of clashing files in the whole repository 
CLASHING=`find "$(git rev-parse --show-toplevel)" | sort | uniq -d -i` 

# Restore previous state 
git stash pop -q 

if [[ $CLASHING ]]; then 
    echo "Found clashing files on case-insensitive file systems" 
    echo "$CLASHING" 
    exit 1 
fi 

exit 0 

这个脚本需要Git版本> = 1.7.7,因为它使用藏匿-u,避免因没有按规定未跟踪文件。

+1

它可能会在'.gitignore'中的未跟踪文件上失败。 – djjeck 2013-01-02 02:55:19

+0

有谁知道如何获得当前树,包括阶段性变化?注意,简单地将'git diff --staged'附加到'HEAD'还不够好;例如,当你改变一个文件名的情况下它不会工作。 – djjeck 2013-01-02 02:57:33

+0

伟大的解决方案。说“不要那样做”是非常无益的。我不认为一个合理的商店会允许两个文件或文件夹,即使他们使用Linux也仅在不同情况下有所不同。 – 2015-07-22 19:52:20

1

真正解决这个问题的最简单方法是重命名这些文件之一,所以他们不会像Windows或OS X.

不区分大小写的文件系统上的冲突之后从Linux提交/ Unix系统,你可以最轻松地解决这个问题,拉一下后,Windows上的一切都会很好。为了防止发生这个问题,你需要添加一个类似于djjeck建议的提交钩子。

这种情况的Windows上的症状是非常混乱,包括:

  • 文件一直显示,即使你回复他们,这使得改变分支或基础重建非常困难,因为改变。只有在情况下,不同的混帐GUI

均显示变化由于两个文件名称的文件

  • 两份不能在不区分大小写的平台共存,你必须改变文件名中的一个,以避免麻烦。