Ste*_*eve 3 git git-submodules
多年来,这已经被问过很多次,但从未见过真正的答案。
我想将一些开源代码作为子模块添加到我现有的项目中,但我只能使用特定的提交 SHA1。
我已经建立了一个例子来演示这个问题。
所以,我的主要项目是:
https://github.com/BitvuLtd/myProj
Run Code Online (Sandbox Code Playgroud)
如您所见,该项目中有一个子模块指向:
https://github.com/BitvuLtd/strangersPro/tree/bd06980e0d711348bc7831f6421b3c5b27948781
Run Code Online (Sandbox Code Playgroud)
我想指出该行的下一个提交:
https://github.com/BitvuLtd/strangersPro/tree/1463dd07645ce4e0450aabaa952b4c657d
我不想要最新的提交,因为它不兼容。
我最接近的是能够使用以下命令在子模块的单独克隆副本中检出正确的提交:
git checkout 1463dd07645ce4e0450aabaa952b4c657d16da39
Run Code Online (Sandbox Code Playgroud)
但是如果我在主项目的子模块目录中这样做,它会得到:
fatal: reference is not a tree: 1463dd07645ce4e0450aabaa952b4c657d16da39
Run Code Online (Sandbox Code Playgroud)
为此,您需要将子模块的 Git 存储库更新为所需的提交(这是一次提交,而不是树),然后在超级项目中运行git add和git commit:
$ cd strangersPro
$ git checkout 1463dd07645ce4e0450aabaa952b4c657d16da39
Run Code Online (Sandbox Code Playgroud)
然后回到超级项目git add strangersPro并提交:
$ cd ..
$ git add strangersPro
$ git commit
Run Code Online (Sandbox Code Playgroud)
定义:子模块是一个 Git 存储库(不是一个非常有用的定义,但也不是完全错误)。术语“子模块”以几种不同的方式使用。通常“子模块”的意思是“用作子模块的 Git 存储库”,这是一个糟糕的定义,因为它有点回避问题,但无论如何让我们继续。:-)
定义:超级项目是一个 Git 存储库,其中至少包含一个子模块。
定义:gitlink是对另一个 Git 存储库的引用。这样的参考由两个项目组成:
要将新的gitlink添加到 Git 存储库,以便此 Git 存储库成为包含子模块的超级项目,您必须在某个时候(每个子模块一次)运行git submodule add. 这将创建或更新转换表。我们需要这个表是因为 gitlink 中存储的名称是一个路径名,例如strangersPro.
此表的(文件)名称是.gitmodules,并且每个子模块包含几行。
在这种特殊情况下,这已经完成了:有一个.gitmodules文件,其中包含以下几行:
[submodule "strangersPro"]
path = strangersPro
url = https://github.com/BitvuLtd/strangersPro
Run Code Online (Sandbox Code Playgroud)
现在我们有了包含此条目的文件,我们可以创建这些特殊的 gitlink 条目之一。gitlink 分为两部分。一个看起来像文件或目录/文件夹名称 - 在这种情况下,strangersPro. 另一个是提交哈希 ID。
路径名strangersPro很容易看到。提交哈希 ID 并不容易看到。 但是 gitlink 条目同时提供了两者。同时,该.gitmodules文件为您的 Git 提供了知道克隆一个单独的Git 存储库的方式,即子模块:该.gitmodules文件说要使用strangersPro,您的 Git 应该在目录下克隆另一个存储库——子模块本身strangersPro。
现在您的超级项目内部有第二个 Git 存储库(在 中strangersPro),您的超级项目的 Gitgit checkout在子模块中运行另一个。第二个git checkout使用 gitlink 中的提交哈希来检查一个特定的提交。
既然您已有一个 gitlink,您的任务就变成:更改哈希 ID。
你这样做多少你在资源库中更改任何文件的方式:通过使一个新的提交后运行git add。也就是说,gitlink是在检查到每一个承诺以同样的方式,任何其他文件一样README.md,在检查每一个承诺。
但是,哈希 ID 只是无意义的大数字,您不能直接编辑“gitlink 文件”(它仅保存在超级项目的索引/暂存区中,而不是常规的工作树文件中)。因此,要更新 gitlink,您必须首先导航到子模块本身:
$ cd strangersPro
Run Code Online (Sandbox Code Playgroud)
这个子模块本身就是一个 Git 存储库,就像任何其他 Git 存储库一样。这意味着你可以运行git checkout,并git status和git branch和git add和git commit等。但是您在这里要做的就是检查一个新的特定提交。您将需要大的废话哈希 ID。幸运的是你在上面提供了这个:它是1463dd07645ce4e0450aabaa952b4c657d16da39.
$ git checkout 1463dd07645ce4e0450aabaa952b4c657d16da39
Run Code Online (Sandbox Code Playgroud)
现在你的子模块在这次提交中有一个分离的 HEAD(而不是它之前的旧的分离的 HEAD)。
现在您导航出子模块存储库,回到超级项目。您现在可以git add使用子模块路径。您的超级项目 git 将从子模块中读取当前提交哈希 ID,并将其添加到您的超级项目的索引中:
$ cd ..
$ git add strangersPro
Run Code Online (Sandbox Code Playgroud)
现在您终于准备好在超级项目中提交,在现有名称下记录新的哈希 ID。