【问题标题】:Git thinks a file within a symlinked directory has been deleted after recreating the symlink, how can I fix it?Git认为重新创建符号链接后符号链接目录中的文件已被删除,我该如何修复它?
【发布时间】:2020-03-07 20:51:25
【问题描述】:
我的存储库中有一个符号链接目录,它链接到文件系统上其他地方的文件。无论出于何种原因,符号链接不时中断,并变成一个常规的空文件夹。所以我删除了空文件夹,并使用ln -s ../../ ext 重新创建了符号链接,这似乎已经奏效,因为我可以浏览该文件夹并查看内容。但是当我运行git status 时,似乎所有应该在ext 文件夹中可见的文件都丢失了。如何让 git 在符号链接目录中再次看到它们?
顺便说一下,这是在 Ubuntu 18 上。
【问题讨论】:
标签:
linux
git
ubuntu
symlink
【解决方案1】:
您的设置很奇怪,因为 Git 不遵循符号链接,它只是存储它们。
也就是说,如果你有一个符号链接 ext -> ../.. 并且你运行 git add ext,Git 会在索引中创建一个模式为 120000(符号链接)的条目来存储 blob 内容 ../..。提交将创建一个提交,当提取该提交时,将创建指向../.. 的符号链接ext。 Git 不会存储任何文件在 ext 存储此符号链接时。
另一方面,如果您有一个包含名为 ext/foo 和 ext/bar 的文件的现有提交,并且您在此提交处克隆此存储库,或者将此提交提取到一个新的空工作树中, Git 会看到,为了写入名为ext/foo 和ext/bar 的文件,您的操作系统要求ext 作为目录存在。因此,它会创建空的目录ext,然后它会在其中创建文件foo 和bar,因为您的操作系统需要,以便创建文件到 Git 仅命名为 ext/foo 和 ext/bar。这两个名称,ext/foo 和 ext/bar,现在将在索引中,因此您进行的下一次提交也将包含这两个文件。
听起来像你:
- 克隆了一个存储库(可能使用
git clone --no-checkout?);
- 在名为
ext 的工作树中手动创建了一个符号链接,指向某个现有目录(可能其中包含一些文件);
- 说服
git checkout 创建ext/foo 和ext/bar,而无需先删除符号链接ext 并将其替换为目录ext。
这不是受支持的操作模式1,当它出错时,您不应该感到惊讶。
1这会导致安全问题:Git 的本意是不写入工作树区域“外部”的任何文件,并且写入文件“下”到工作外部目录的符号链接-tree 将允许这种情况发生。与其仔细限制符号链接的使用,Git 通常不会首先存储“超出”任何链接的文件——尽管通过仔细操作索引和操作系统级别的文件系统,这可能是可能的。工作树驻留,手动欺骗 Git。