嵌套的相对符号链接在操作系统和 git 中如何运行?

嵌套的相对符号链接在操作系统和 git 中如何运行?

在不同操作系统中使用 git 时,我试图弄清楚当相对符号链接位于另一个符号链接“内部”时其行为如何。

以下是一个例子:

a (file)
b (folder)
  a (symlink to `../a`)
c (folder)
  a (file)
  b (symlink to `../b`)

/c/b/a引用/a/c/a?我希望它引用/a。这在 Linux、Windows、MacOS 和 Git 中是否一致?如果我将这样的结构推送到 Git,然后再次将其拉出,我会得到我想要的行为吗?

答案1

符合 POSIX 标准的系统

POSIX 路径名解析似乎定义得很好。希望 Linux 和 macOS 在这方面符合 POSIX 标准。

符号链接和的规则..在这里。前置概念意味着为了解析,/c/b/a进程需要按照这个顺序解析/c和。具体来说,它需要ba

  • 解析/,结果是/
  • 解决c上一步的结果:
    • c在 中查找//c
    • 了解它是一个目录,
    • 结果是/c
  • 解决b上一步的结果:
    • b在 中查找/c/c/b
    • 得知这是一个符号链接,
    • b用符号链接的内容替换:/c/b变成/c/../b
    • 解析/c/../
    • b在 中查找//b
    • 了解它是一个目录,
    • 结果是/b
  • 解决a上一步的结果:
    • a在 中查找/b/b/a
    • 了解到它是一个符号链接(在某些情况下,过程到此停止,最终结果是/b/a;如果“该函数需要对符号链接本身起作用,或者某些参数指示该函数对符号链接本身起作用”,就会发生这种情况),
    • a用符号链接的内容替换:/b/a变成/b/../a
    • 解析/b/../
    • a在 中查找//a
    • 了解到它不是一个符号链接,
    • 最终结果是/a

结果永远不会是/c/a。要获得/c/a该过程,需要解决a现有的/b,而仍然指的b/c/b;所以在某个时候它会解析/c/b/../a/c/a。但要找到ab需要从/c/b/c/../b/b 第一的.才算a解决。

但是如果/c/b是一个目录并且/b被绑定挂载在那里,那么/c/b/a确实会解析为/c/a。 关键的区别是/c/b在这种情况下 不是符号链接。

如果原始路径名包含..,则某些工具可能会在处理 实例后解析符号链接..。例如:cd -L; 比较这个答案。但就您而言,这是..从符号链接出现的,因此此问题不适用。


Git

Git 是由 Linux 内核的主要开发者 Linus Torvalds 创建的。猜测它完全兼容 Linux 解释符号链接的方式。我完全没有使用 Git 的经验,所以我不确定。不过,在阅读Git 如何处理符号链接?我相信“将这样的结构推送到Git,然后再次拉取”没有问题。


视窗

微软

符号链接旨在帮助实现与 UNIX 操作系统的迁移和应用程序兼容性。Microsoft 已实现其符号链接,其功能与 UNIX 链接相同。

维基百科不过,这两者之间几乎没有什么区别。就你的问题而言,以下这段话可能有意义:

在 Windows Vista 及更高版本中,当工作目录路径以符号链接结尾时,当前父路径引用..将引用符号链接的父目录,而不是其目标的父目录。这种行为在至少一些 POSIX 系统(包括 Linux)的 shell 级别也存在,但在通过操作系统调用访问文件和目录时从未出现过。

(上面提到了 Linux 中 shell 级别的这种行为。)

再加上非管理员用户默认无法创建符号链接

在 Windows 7 NTFS 中,我创建了所需的目录结构并进行了一些测试。命令行工具(例如copy)似乎解析\c\b\a\a。但是explorer.exe,在导航到\c\b并双击后a,会打开\c\a。另一方面,如果我拖动并进行复制,则会复制a的内容。\a

我注意到我可以通过双击窗口的主区域\c\b来转到;但如果我在树(导航窗格)中选择,那么程序就会跳转到始终所在的位置。\cb\c\b\ba\a

相当不一致。我还没有测试过较新的 Windows 系统,或许他们更好。

相关内容