40

我们在 unix 中有一个 git 裸存储库,该存储库具有相同名称的文件,仅在某些情况下有所不同。

例子:

GRANT.sql
grant.sql

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

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

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

4

7 回答 7

42

Windows 不区分大小写(更准确地说,保留大小写)。根本不可能存在两个名称仅大小写不同的文件:两个仅大小写不同的文件名是相同的文件名。时期。

因此,Git 遍历存储库,一个接一个地检查文件,直到找到两个问题文件中的第一个。Git 对其进行检查,然后进一步处理其业务,直到遇到第二个文件。再次,Git 检查它。由于从 Windows 的角度来看,文件名与第一个文件名相同,因此第一个文件只会被第二个文件覆盖。这现在让 Git 认为第一个文件已更改为与第二个文件具有相同的内容。

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

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

core.ignorecase在这里不会对您有所帮助,因为它可以处理完全相反的问题。

于 2010-03-27T15:45:08.387 回答
34

我刚刚遇到了类似的问题。就我而言,这两个名称相似的文件仅在大小写不同时位于与 Windows 克隆无关的子目录中。Git 1.7 具有稀疏检出功能,可让您从工作副本中排除某些文件。要排除此目录:

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专门排除这些文件。

于 2010-07-23T02:56:06.477 回答
4

我不确定这是否可能。Git 的 ignorecase 处理一个文件情况下的差异。它无法解决 Window 无法在一个目录中拥有两个仅因大小写而异的文件名的问题。

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

于 2010-03-27T08:09:28.840 回答
3

如果你想让你的存储库对不区分大小写的文件系统友好,你可以添加一个提交钩子来防止你签入冲突文件。

#!/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,以避免在未跟踪的文件上失败。

于 2013-01-02T01:46:03.490 回答
1

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

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

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

有关Cygwin 如何支持区分大小写的一些注意事项,请参见此处。

于 2011-10-16T05:05:20.120 回答
1

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

在 Linux/Unix 系统提交之后,您可以最轻松地解决问题,在拉取之后,Windows 上的一切都会好起来的。为了防止这个问题发生,你需要添加一个类似于 djjeck 建议的提交钩子。

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

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

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

于 2015-08-04T13:44:30.970 回答
0

另一种可以避免的简单方法git read-tree --reset -u HEAD

1. Clone without checking out
  `git clone --no-checkout`

2. Configure sparse checkout

3. Check out required branch
`git checkout -b branch_name remotes/origin/branch_name`
于 2022-02-09T05:47:29.187 回答