Git-windows区分大小写的文件名未正确处理

时间:2010-03-27 08:01:39

标签: git msys

我们在unix中有一个git裸存储库,它具有同名的文件,只有在不同情况下才会有所不同。

示例:

GRANT.sql
grant.sql

当我们将裸存储库从unix克隆到windows框时,git status会将文件检测为已修改。工作树仅使用grant.sql加载,但git status比较grant.sql和GRANT.sql,并在工作树中显示已修改的文件。

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

有没有办法解决这个问题?

6 个答案:

答案 0 :(得分:40)

Windows不区分大小写(更确切地说,保留大小写)。根本没有可能的方法存在两个文件,其名称仅在大小写上有所不同:两个仅在大小写不同的文件名是相同的文件名。周期。

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

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

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

core.ignorecase在这里不会帮助你,因为它可以处理相反的问题。

答案 1 :(得分:33)

我刚遇到类似的问题。在我的例子中,具有相似名称的两个文件仅在大小写不同的子目录中与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以专门排除这些文件。

答案 2 :(得分:4)

我不确定这是否可行。 Git的ignorecase处理一个文件的差异。它不能解决Window无法在一个目录中只有两个文件名的区别。

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

答案 3 :(得分: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,因为它使用stash -u,以避免在未跟踪文件上失败。

答案 4 :(得分:1)

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

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

HKLM \ System \ CurrentControlSet \ Control \ Session Manager \ Kernel \ ObCaseInsensitive = 0

有关Cygwin支持区分大小写的一些注意事项,请参阅here

答案 5 :(得分:1)

实际解决问题的最简单方法是重命名其中一个文件,以便它们不会在不区分大小写的文件系统(如Windows或OS X)上发生冲突。

在Linux / Unix系统的提交之后,您可以最轻松地解决问题,在拉动后,Windows上的一切都会正常。为了防止出现此问题,您需要添加类似于djjeck建议的提交挂钩。

Windows上的症状非常令人困惑,包括:

  • 即使您还原它们也会显示为已更改的文件,这会使更改分支或变基非常困难。
  • 两个名称不同的文件副本仅在git gui
  • 中显示更改的情况下有所不同

由于两个文件不能在不区分大小写的平台上共存,因此您必须更改其中一个文件名以避免麻烦。