这些年来已被问过很多次,但从未见过真正的答案。
我想将一些开源代码作为子模块添加到现有项目中,但我只能使用特定的提交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
答案 0 :(得分:1)
为此,您需要将子模块的Git存储库更新为所需的提交(提交,而不是树),然后在超级项目中运行git add
和git commit
:
$ cd strangersPro
$ git checkout 1463dd07645ce4e0450aabaa952b4c657d16da39
然后返回超级项目并git add strangersPro
并提交:
$ cd ..
$ git add strangersPro
$ git commit
定义:子模块是一个Git存储库(不是一个非常有用的定义,但不完全是错误的)。术语“子模块”以几种不同的方式使用。通常“子模块”意味着“一个Git存储库被用作子模块”,这是一个可怕的定义,因为它有点begs the question,但不管怎么说,让我们继续使用它。 : - )
定义: superproject 是一个Git存储库,其中至少包含一个子模块。
定义: gitlink 是对另一个Git存储库的引用。这样的参考包括两个项目:
要将 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条目同时提供两者。同时,.gitmodules
文件为您的Git提供了克隆单独的 Git存储库的方式,即子模块:.gitmodules
文件表示要使用{{1}你的Git应该在strangersPro
目录下克隆另一个存储库 - 子模块本身。
现在您的超级项目中有第二个Git存储库(在strangersPro
中),您的超级项目的Git在子模块中运行另一个strangersPro
。第二个git checkout
使用gitlink中的提交哈希来检查一个特定的提交。
现在你有了一个现有的gitlink,你的任务就变成了:更改哈希ID 。
您执行此操作的方式与更改存储库中的任何文件的方式相同:在运行git checkout
后进行新提交。也就是说,gitlink 在中检查每个提交,就像检查每个提交中的任何其他文件(如git add
一样)。
README.md
这个子模块本身就是一个Git存储库,就像任何其他Git存储库一样。这意味着您可以投放$ cd strangersPro
和git checkout
以及git status
和git branch
以及git add
,依此类推。但是你想要做的就是检查一个新的特定提交。您将需要大量无意义的哈希ID。幸运的是,您提供了以上内容:它是git commit
。
1463dd07645ce4e0450aabaa952b4c657d16da39
现在你的子模块在这个提交时有一个分离的HEAD(而不是之前的旧的分离HEAD)。
现在您将子模块存储库的 out 导航回超级项目。您现在可以$ git checkout 1463dd07645ce4e0450aabaa952b4c657d16da39
子模块路径。您的超级项目git将从子模块中读取当前的提交哈希ID,并将其添加到您的超级项目的索引中:
git add
现在您已经准备好在超级项目中提交,在现有名称下记录新的哈希ID。