【问题标题】:git: symlink/reference to a file in an external repositorygit:符号链接/对外部存储库中文件的引用
【发布时间】:2013-04-05 22:16:38
【问题描述】:

在 git 中是否有可能在 git repo 中有一个特定文件的“链接”?就像 git 子模块对文件夹所做的那样,但我的问题是关于特定文件,而不是完整目录:

my-project/
    class1.java
    class2.java
    logback.xml (link to a particular file, say https://github.com/theHilikus/JRoboCom/blob/master/jrobocom-core/src/main/resources/logback.xml)

可以看出,在这种情况下,拥有一个完整的子模块文件夹是没有意义的,它只是一个文件。
我可以将链接锁定到特定提交,但如果它在其自己的项目生命周期中发生变化时移动会更好

请注意,这与文件系统的符号链接无关;我说的是对另一个项目、repo、分支或任何东西中的文件的引用。如果文件的内容是重复的而不是文件系统符号链接,那也没关系

【问题讨论】:

标签: git


【解决方案1】:

Git 具有可用于实现所需功能的功能。它支持文件系统符号链接并支持子模块。子模块已经是处理对其他存储库的引用的标准方法。您可以将它们与本地引用文件的方式结合使用。这可以使用相对符号链接直接处理,也可以使用脚本间接处理,该脚本将文件从子模块复制到您需要的位置。

每个外部 git 树应该有一个子模块,并且应该小心对待这些子模块,因为它们不仅是指向外部存储库的链接,而且是指向它们特定提交的链接。以下解决方案将向您展示如何使用外部存储库中的单个文件,但仍保持子模块的所有优点。

另一种方法是直接获取文件,但是您将完全失去子模块的优势,或者您必须自己构建功能。正如我已经说过的,子模块是处理此类任务的标准方法,除非您有特殊需要,例如避免不惜一切代价下载其他文件,否则您应该使用它。

使用子模块和符号链接

准备好子模块后,您可以添加指向子模块目录结构的文件系统符号链接。

在项目目录的 shell 中运行它:

$ git submodule add https://github.com/theHilikus/JRoboCom
$ ln -s JRoboCom/jrobocom-core/src/main/resources/logback.xml
$ git add .gitmodules logback.xml
$ git commit -m "add a symbolic link to logback.xml with the respective submodule"

现在你有一个符号链接:

logback.xml -> JRoboCom/jrobocom-core/src/main/resources/logback.xml

使用子模块和脚本

作为替代方案,您可以使用自定义脚本从子模块中复制普通文件。在非常特殊的情况下,您可以在没有子模块的情况下从脚本处理外部存储库,但我通常不推荐它。

创建一个文件bootstrap.sh,其中包含:

#!/bin/sh
git submodule init
git submodule update

cp JRoboCom/jrobocom-core/src/main/resources/logback.xml .

在项目目录的 shell 中运行它:

$ git submodule add https://github.com/theHilikus/JRoboCom
$ git add .gitmodules bootstrap.sh
$ git commit -m "add a script to fetch logback.xml from the respective submodule"

请注意,我们不会将 logback.xml 文件添加到 Git,因为它将从子模块中获取。

指示存储库的用户首先运行上面的脚本。它将准备他们的存储库以使用子模块,将获取子模块数据并将文件复制到其位置。有时项目中已经有某种引导脚本。

使用脚本通过 git 协议获取单个文件

使用 git archive 找到了 Git >= 1.7.9.5 的另一个解决方案。

创建一个文件 bootstrap.sh,其中包含:

#!/bin/sh
git archive --remote=https://github.com/theHilikus/JRoboCom master:JRoboCom/jrobocom-core/src/main/resources logback.xml | tar -x

在项目目录的 shell 中运行它:

$ git add bootstrap.sh
$ git commit -m "add a script to fetch logback.xml directly from the remote project"

使用脚本通过 HTTP 获取单个文件

如果存储库托管服务还通过 HTTP 提供单个文件,您只需使用 curlwget 下载它们。

创建一个文件 bootstrap.sh,其中包含:

#!/bin/sh
curl -O https://raw.githubusercontent.com/theHilikus/JRoboCom/master/jrobocom-core/src/main/resources/logback.xml

在项目目录的 shell 中运行它:

$ git add bootstrap.sh
$ git commit -m "add a script to fetch logback.xml directly from github"

脚本获取单个文件的注意事项

您还可以将引用存储在具有特定扩展名的文件中(如*.url)或在一个文件中维护引用列表(如项目目录中的.references)并构建一个更全面的脚本来遍历所有参考并下载相应的文件。

【讨论】:

  • 我猜这在 Windows 中不起作用,因为使用了符号链接?还是有 Windows 解决方法?
  • 克隆 repo 时是否会执行 bootstrap.sh ?
  • 我试图使用 git 协议获取单个文件,并且 repo 在 github 上。目前 github 服务器不支持 Git 存档。另一种方法是使用 stackoverflow.com/a/18324428/999165 中提到的 svn。
【解决方案2】:

接受的答案似乎具有误导性,因为 只要所有开发人员使用的操作系统都支持,Git 就可以很好地处理符号链接

默认情况下,Git 会尝试存储符号链接而不是跟随它们(为了紧凑和人们通常想要的)。

当您检出包含链接的树时,无论目标文件系统对象是否存在,它都会将该对象恢复为符号链接。

如果您在不支持符号链接的 FAT 等文件系统上,并且您的存储库使用它们,您可以将 core.symlinks 配置变量设置为 false,并且符号链接将作为包含链接文本的小型纯文本文件检出.

SO 参考资料:

How does git handle symbolic links?

Git - how to handle symlinks

How can I get git to follow symlinks?

【讨论】:

  • 这个答案讲的是内部符号链接,而不是外部资源的符号链接,请参阅我的答案。
  • 真的吗?请再次阅读标题,然后阅读第一句话。
  • 我不明白你的意思。此外,如果您投了反对票,最好发表评论来解释反对票,如果那是您的的话。 Downvoting 是一种 QA 工具,而不是报复工具。
  • @PavelŠimerda 当我遇到这个问题/答案时,我正在寻找一个类似的主题,这个问题/答案恰好是我的一个朋友问的(他会认出我)。当我看到答案时,我只是(通过帖子)向他指出,基于这个问题,接受的答案似乎非常具有误导性。如果不熟悉 GIT 和符号链接的人遇到这个问题,我不希望他们立即认为 GIT 不支持符号链接。您可以随意投反对票。
  • @Jeach 查看原始问题的最后一段。你误解了第一句话。
【解决方案3】:

晚了几年,但请查看DVC 工具,这些工具可让您 git 版本跟踪或链接存储在远程存储中的任何类型的文件。该工具具有独立于平台的文件链接方式。

【讨论】:

    【解决方案4】:

    很遗憾,没有。您可以在 git 中拥有的唯一外部引用类型是通过子模块,它将整个分支放在一个目录中。您需要创建一个脚本或其他东西来帮助从所需位置获取文件并将其放入您的工作树中。

    【讨论】:

    • 子模块是处理外部引用的标准方式。您可以将它们与文件系统符号链接或脚本一起使用,请参阅我的回答。
    • @PavelŠimerda 是的,但你只能将一整棵树作为子模块——我已经在我的回答中说明了这一点。 OP 想要指向一个 single file,而子模块无法做到这一点。抱歉,您的回答对对话没有任何帮助。
    • 我的回答描述了两种不同的解决方案来使用子模块指向文件。我对它进行了大量编辑,我希望现在的意图更加清晰。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-07
    • 2018-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-15
    • 2017-12-21
    相关资源
    最近更新 更多