【问题标题】:Adding a submodule with a specific SHA1 to an existing git repo将具有特定 SHA1 的子模块添加到现有的 git 存储库
【发布时间】:2017-06-23 18:01:44
【问题描述】:

多年来,这个问题已经被问过好几次了,但从未见过真正的答案。

我想将一些开源代码作为子模块添加到我现有的项目中,但我只能使用特定的提交 SHA1。

我已经设置了一个例子来演示这个问题。

所以,我的主要项目是:

https://github.com/BitvuLtd/myProj 

如您所见,该项目中有一个子模块指向:

https://github.com/BitvuLtd/strangersPro/tree/bd06980e0d711348bc7831f6421b3c5b27948781

我想指出下一个提交:

https://github.com/BitvuLtd/strangersPro/tree/1463dd07645ce4e0450aabaa952b4c657d

我不想要最新的提交,因为它不兼容。

我最接近的是能够检查正确的提交是在子模块的单独克隆副本中,使用:

git checkout 1463dd07645ce4e0450aabaa952b4c657d16da39

但是如果我在主项目的子模块目录中这样做,它会得到:

fatal: reference is not a tree: 1463dd07645ce4e0450aabaa952b4c657d16da39

【问题讨论】:

  • 你在签出提交之前拉取了子模块吗?您需要将提交放在本地存储库中才能将其签出。

标签: git git-submodules


【解决方案1】:

TL;DR:你需要更新你的 gitlink

为此,您需要将子模块的 Git 存储库更新为所需的提交(这是一个提交,而不是树),然后在超级项目中运行 git addgit commit

$ cd strangersPro
$ git checkout 1463dd07645ce4e0450aabaa952b4c657d16da39

然后回到超级项目并git add strangersPro 并提交:

$ cd ..
$ git add strangersPro
$ git commit

详情

定义:submodule 是一个 Git 存储库(不是一个非常有用的定义,但也不完全是 错误)。术语“子模块”以几种不同的方式使用。通常,“子模块”的意思是“将 Git 存储库用作子模块”,这是一个糟糕的定义,因为它有点像 begs the question,但不管怎样,让我们​​继续吧。 :-)

定义:超级项目是一个 Git 存储库,其中至少包含一个子模块。

定义:gitlink 是对另一个 Git 存储库的引用。这样的参考由两个项目组成:

  • 我们用来命名特定的其他 Git 存储库的东西,以及
  • 特定提交的哈希 ID(我们假设)存在于其他 Git 存储库中。

你要做的是添加或更新一个 gitlink

要将 new gitlink 添加到 Git 存储库,以便此 Git 存储库成为包含子模块的超级项目,您必须在某个时候(每个子模块一次)运行git submodule add。这将创建或更新转换表。我们需要这张表是因为 gitlink 中存储的名字是一个路径名,比如strangersPro

此表的(文件)名称为.gitmodules,每个子模块包含几行。

在这种特殊情况下,这已经完成:有一个 .gitmodules 文件,其中包含这些行:

[submodule "strangersPro"]
    path = strangersPro
    url = https://github.com/BitvuLtd/strangersPro

现在我们有了这个包含这个条目的文件,我们可以创建这些特殊的 gitlink 条目之一。 gitlink 分为两部分。一个看起来像文件或目录/文件夹名称——在本例中为strangersPro。另一个是提交哈希 ID。

路径名strangersPro 很容易看到。提交哈希 ID 不那么容易看到。 但 gitlink 条目同时提供 both。同时,.gitmodules 文件为您的 Git 提供了克隆 单独 Git 存储库(即子模块)的方法:.gitmodules 文件表示要使用 strangersPro,您的 Git 应该在strangersPro 目录下克隆另一个 存储库——子模块本身。

现在您的超级项目内部有第二个 Git 存储库(在 strangersPro 中),您的超级项目的 Git 在子模块中运行另一个 git checkout。第二个 git checkout 使用 gitlink 中的提交哈希来检查一个特定的提交。

更新 gitlink

现在你已经有了一个现有的 gitlink,你的任务变成了:改变哈希 ID

您执行此操作的方式与更改存储库中的任何文件大致相同:在运行git add 后进行新提交。也就是说,gitlink 被签入到每个提交,就像任何其他文件,如README.md,被签入每个提交一样。

不过,哈希 ID 只是无意义的大数字,您不能直接编辑“gitlink 文件”(它只保存在超级项目的索引/暂存区,而不是常规的工作树文件中)。因此,要更新 gitlink,您必须首先导航到子模块本身:

$ cd strangersPro

这个子模块本身就是一个 Git 存储库,就像任何其他 Git 存储库一样。这意味着您可以运行git checkoutgit statusgit branchgit addgit commit 等等。但是您在这里要做的就是检查一个新的特定提交。您将需要大的废话哈希 ID。幸运的是你在上面提供了这个:它是1463dd07645ce4e0450aabaa952b4c657d16da39

$ git checkout 1463dd07645ce4e0450aabaa952b4c657d16da39

现在您的子模块在此提交时有一个分离的 HEAD(而不是之前的旧分离 HEAD)。

现在您导航 子模块存储库,回到超级项目。您现在可以git add 子模块path。您的超级项目 git 将从子模块中读取当前的提交哈希 ID,并将其添加到您的超级项目的索引中:

$ cd ..
$ git add strangersPro

现在您终于准备好在超级项目中提交,将新的哈希 ID 记录在现有名称下。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-10
    • 2017-06-29
    • 2012-09-23
    • 2013-04-30
    • 1970-01-01
    • 2015-04-09
    • 2020-12-06
    • 2011-06-04
    相关资源
    最近更新 更多