Git 将目录符号链接创建为文件

Git creates directory symlink as a file

给定 repo 中的两个普通文件夹:

drwx------ dir_a/
drwx------ dir_b/

我将 dir_b 转换为指向 dir_a 的相对符号链接(即 rm -rf dir_bln -s dir_a dir_b,现在它看起来像:

drwx------ dir_a/
lrwxrwxrwx dir_b -> dir_a/

在另一台机器上提交、推送和拉取后,我看到 dir_b 显示为普通文件而不是文件夹符号链接

$ ls -al
drwx------ dir_a/
-rw------- dir_b

尝试删除 dir_b 并使用 git checkout dir_b 恢复它,但它仍然被重新创建为文件,而不是文件夹符号链接。文件系统是 ext4,支持符号链接。事实上,在同一分区上执行新的 git clone 确实会按预期创建 dir_b 作为符号链接。

以防万一,我会提到 dir_b 的实际名称以点开头(例如 .dir_b)。

git clone 工作正常,所以我可以将其用作解决方法,但想知道到底发生了什么以及恢复符号链接文件夹的正确方法是什么,因为显然 git checkout symlinked_folder 不会重新创建原始仓库中的文件夹。

这种情况下的修复是 运行:

git config core.symlinks true

(检查其他非默认设置可能是明智的,特别是如果 SD 卡存储库是由不同的 OS 创建的。)

正如评论中所讨论的那样,这里的关键要素是存储库最初是在不支持符号链接的文件系统上创建的,然后移动(手动复制)到支持符号链接的文件系统。 The git config documentation,在下面描述 core.symlinks 的部分中说:

If false, symbolic links are checked out as small plain files that contain the link text. git-update-index(1) and git-add(1) will not change the recorded type to regular file. Useful on filesystems like FAT that do not support symbolic links.

The default is true, except git-clone(1) or git-init(1) will probe and set core.symlinks false if appropriate when the repository is created.

一般来说,在逻辑或物理驱动器之间移动存储库时 git clone 存储库会更安全一些,因为新克隆将探测新文件系统的设置。 Git 相当擅长自动检测其他更改(例如,索引对工作树路径进行编码),并且这些设置中的大多数都是 OS 特定的,而不是特定于文件系统的。但是,如果您交叉引导不同的 OSes(或 运行 它们在管理程序下)并在两者之间共享一些媒体,这些额外的 core.* 设置可能会导致问题。参见,例如 core.fileModecore.protectNTFS