"git submodule update"和"git pull"之间的区别是什么?"

4
如果有的话,“git submodule update”和进入git子模块目录并在每个目录上执行“git pull”的区别是什么?
谢谢。

请展示一下你目前找到的文档/资源。 - Raffael
1个回答

5
有所不同。此外,我要注意的是,我刻意避免子模块(也称为 sob 模块,有很好的理由:它们会让用户非常难过或沮丧,或者两者都有)。
子模块是一个单独的 Git 存储库。
为了区分“主”或“超级项目”和每个“子模块”,让我们称顶层为超级项目。当我们将它们作为存储库处理时,子项目、子模块或子存储库都只是“子存储库”。
超级项目是普通的 Git 存储库。它像往常一样有分支,并且在分支上有提交(还可以选择提交不在分支上等)。对于每个子模块,它还记录了一些信息:
- 子模块存储库的 URL - 子模块存储库的路径 - 子模块的提交 ID
前两个项目存储在.gitmodules中,它是超级项目工作树顶部的普通文件,格式为git config文件(如$HOME/.gitconfig.git/config)。.gitmodules文件还可以包含其他信息,针对每个子模块,但前两个项目是必需的。
第三个项目——提交ID存储在仓库中,类型为“gitlink”的文件中。这是在更改特定子模块要使用哪个提交时更新的文件。
假设超级项目有两个子模块,libbiglibsmall,位于路径libs/biglibs/small下。因此,您将具有.gitmodules,其中路径libs/biglibs/smallURLs可能是任何内容,取决于libbiglibsmall的上游存储库在哪里。
同时,在你的超级项目中,Git 将记录一个名为 libs/big 的“文件”,其内容为 1a987f1356... 或其他内容,以及另一个名为 libs/small 的“文件”,其内容为另一个大丑陋的 SHA-1 哈希值。

每个子模块都处于“分离 HEAD”状态

当您克隆并检出超级项目时,还没有子模块的仓库,您只有 .gitmodules 文件和存储的提交 ID。使用 git submodule update 将克隆存储库到适当的目录中。然后,它将检出由 gitlink 条目标识的特定提交

这会将每个子存储库放入“分离 HEAD”状态。

(即使对于所有新的“分支”模式,似乎也是如此,尽管我没有进行实验。)

git pull = git fetch + git something

运行 git pull 实际上只运行了一个有限的 git fetch,然后是另一个 Git 命令:要么 git merge 要么 git rebase。在 fetch 步骤中使用哪个远程分支以及在合并或变基步骤中使用哪个分支由您当前的分支控制。这两个设置的值组合起来构成了当前分支的 upstream 设置:如果当前分支为 $branch,则其 upstream 为 $remote/$merge,其中 $remote 是运行 git config --get branch.$branch.remote 命令输出的任何内容,$merge 是运行 git config --get branch.$branch.merge 命令输出的内容。

由于您的子仓库处于“分离 HEAD”状态,它的“当前分支”是“无分支”,也称为特殊的匿名分支。按定义,它既没有远程设置也没有合并设置。无论哪个 git config --get 命令都将失败。

由于Git默认从origin获取,因此提取步骤仍然有效。但是,合并或变基步骤将失败。因此git pull的作用不大。

git submodule update完全是另一回事

它具体做什么高度可配置,请参阅文档。通常情况下,如果未配置,则只需进行任何必要的初始化。总的来说,它不会将子模块放在分支上:即使它根据分支名称更新子模块,它仍然处于“分离的HEAD”状态。

小结

子模块的一般思想是不需要关注分支,只需要关注原始提交ID。每个子模块都会说“从这个特定的存储库获取我这个特定的提交”,其中提交ID记录在超级项目中的“gitlink”条目中,子仓库的URL记录在超级项目的.gitmodules文件中。因此,提交ID和URL都包含在超级项目的提交中:通过gitlink“文件”记录ID,通过.gitmodules文件记录URL。
要将某个子模块指向不同的提交ID,只需在子模块本身中检出新的ID,然后进入超级项目并将新的ID“git add”到相应的gitlink中。使用git submodule add为您执行第二步。您几乎可以手动完成第二步(除了文件名自动补全在路径中留下“/”可能导致操作出现问题)。更新所有子模块后,您可以“git commit”结果以在超级项目中创建一个新的提交,记录新的gitlink哈希值。
所有对于git submodule的繁琐操作都是为了完成上述两个步骤(留下git commit步骤需要手动完成)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接