Windows 下使用符号链接进行 git clone 时出错

Windows 下使用符号链接进行 git clone 时出错

使用 git clone 时,出现“警告:以下路径发生冲突(例如,不区分大小写的文件系统上的区分大小写的路径)并且工作树中只有来自同一冲突组的一个路径”错误:

git clone -c core.symlinks=true ssh://[email protected]/etc c/Dev/GIT/mysite-etckeeper/
Cloning into 'c/Dev/GIT/mysite-etckeeper'...
remote: Counting objects: 1400, done.
remote: Compressing objects: 100% (1202/1202), done.
remote: Total 1400 (delta 195), reused 0 (delta 0)
Receiving objects: 100% (1400/1400), 3.71 MiB | 276.00 KiB/s, done.
Resolving deltas: 100% (195/195), done.
Checking out files: 100% (1154/1154), done.
warning: the following paths have collided (e.g. case-sensitive paths
on a case-insensitive filesystem) and only one from the same
colliding group is in the working tree:

  'HOSTNAME'
  'hostname'


/etc # ls -la HOSTNAME
lrwxrwxrwx   1 root root         8 Mar 29  2017 HOSTNAME -> hostname

/etc # ls -la hostname
-rw-r--r--   1 root root        18 Dec 21  2016 hostname

我该如何修复这个问题?这个符号链接问题也导致了其他问题。

以下是重现该错误的示例 repo: https://github.com/klorinczi/test_dupe_filename

Execute this:

$ git clone -c core.symlinks=true https://github.com/klorinczi/test_dupe_filename 
Cloning into 'test_dupe_filename_example'...
remote: Enumerating objects: 9, done.
remote: Counting objects: 100% (9/9), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 9 (delta 0), reused 9 (delta 0), pack-reused 0
Unpacking objects: 100% (9/9), done.
warning: the following paths have collided (e.g. case-sensitive paths
on a case-insensitive filesystem) and only one from the same
colliding group is in the working tree:

  'HOSTNAME'
  'hostname'

答案1

这不是一个符号链接问题,而是一个不区分大小写的文件系统的问题。

在区分大小写的文件系统中,文件ReadMe.txtReadme.txtREADME.txt是三个不同的文件。在不区分大小写的文件系统中,它们是同一个文件。

默认情况下,Windows 和 macOS 使用不区分大小写的文件系统。NTFS 本身区分大小写,但 Windows 只使用它不区分大小写。HFS+ 和 APFS 可以区分大小写,但默认情况下它们不区分大小写。然而,大多数 UNIX 系统和 Linux 默认使用区分大小写的文件系统。

问题是有一个名为的文件hostname和指向该文件的符号链接HOSTNAME。在区分大小写的文件系统上,这是两个不同的名称,因此文件和符号链接可以存在于同一目录中。

但是,在不区分大小写的系统上,hostnameHOSTNAME是相同的文件名,并且同一个文件不能一次是文件,一次是符号链接。

如果 Git repo 需要在区分大小写的文件系统上运行,则该 repo 的所有用户都应该拥有

ignorecase = true

在他们的 Git 配置文件中。如果这是真的,Git 还会将所有对象视为同一个对象,即使它们的名称只是大小写不同。在这种情况下,甚至不可能签入hostnameHOSTNAME一个存储库,因为 Git 会将其视为同一个文件,并且一个文件会覆盖存储库中的另一个文件。

要解决你的情况:

  1. 删除符号链接:git rm -f HOSTNAME
  2. 恢复文件:git restore hostname
  3. 犯罪:git ci -m "Fix hostname/HOSTNAME name conflict"

步骤 2 仅在区分大小写的文件系统上是必需的,因为在这里删除两者中的任何一个都会始终删除磁盘上的文件(正如我所说,从文件系统的角度来看,两者都是同一个文件)。

如果由于某种原因文件需要全部大写,请执行与上述相同的步骤,然后进行双重重命名:

  1. git mv hostname hostname_2
  2. git mv hostname_2 HOSTNAME
  3. git ci -m "Rename hostname to HOSTNAME"

ignorecase = true在不区分大小写的系统中,更改大小写始终需要两次重命名。如果已设置,则在区分大小写的系统中也是如此。

相关内容