重温 Git 子模块

2025-06-08

重温 Git 子模块

Git 的子模块受到了普遍的嘲笑,以至于几乎整个行业都致力于提供管理依赖关系的替代方案。

但就像 git 中的任何东西一样,通常值得仔细阅读手册页并弄清楚是否有一些选项可以满足您的要求,或者看看它们最近是否有所改进。

我想要什么

所以,Metre是我的样板项目。它有很多子模块,部分原因是我们的一些客户运行的是(非常)老旧的 Linux 版本,所以我们需要进行静态链接。耶,真有意思!

但这意味着我们要管理和交付我们自己构建的 OpenSSL 版本——这对我们的安全人员(可爱的西蒙)来说是一个可怕的前景。实际上,对我来说也相当可怕。

那么,实际上,我们的发布周期包括沿着所有子模块的稳定分支推进,这样我们就能确信所有错误都已修复。这需要尽可能简单——实际上,只需要一个命令,我们就可以根据需要运行。

但是,我们希望高度确信检查 Metre 的特定提交哈希将为我们提供与我们构建的相同的依赖关系。

Git 子模块添加

最初,我尝试了git submodule很多手动工作。我(首席开发人员)对此很不满意。安全专家 Simon 也对此很不满意。我们的高级开发人员 Pete 对项目进行了全面审查,并重点指出了这一点。

问题在于,一次失误和一次依赖可能会留下严重的安全问题。而 Metre 的宗旨就是安全。

的优点是它可以跟踪子模块的提交哈希,并且您可以使用git submodule以正确的哈希检查它们git clone --recursivegit submodule update --init --recursive

我们考虑过换用其他产品,但这样一来,我们就会失去很多内置的智能git submodule,这也是一种痛苦。

哦,看——树枝!

man git-submodule然而man 7 gitsubmodules深入研究后,我发现了金子。

首先,有一个-b branch切换到 的开关git submodule add。这会将子模块添加到特定分支,并且还会将“跟踪分支”(git 通常从中拉取的分支)设置为远程 origin 分支,就像你平常做的那样。

其次,我找到了一个配置选项submodule.{submodule name}.branch,用于存储这些信息。不过,这并不像你想象的那么好,因为虽然你可以git config为存储库设置它,但它不会被跟踪。

害怕我的编辑技巧

但是,子模块配置存储在存储库.gitmodules顶部的文件中。因此,您可以编辑该文件,找到相应部分,然后直接branch在其中添加一个键:

[submodule "deps/spiffing"]
        path = deps/spiffing
        url = http://github.com/surevine/spiffing
[submodule "deps/openssl"]
        path = deps/openssl
        url = git://git.openssl.org/openssl.git
        branch = OpenSSL_1_1_0-stable
Enter fullscreen mode Exit fullscreen mode

不过,默认值是master,所以如果这就是您想要的,那么您已经拥有了。

更新分支

更新子模块的常规命令是git submodule update。有三个值得关注的标志:

--initgit submodule init如果子模块尚未克隆到位,则执行,否则不执行任何操作 - 因此始终可以安全使用。

--recursive递归遍历每个子模块,git submodule update在每个子模块中运行相同的命令。

--remote就是那个神奇的——沿着远程跟踪分支执行git pull。这就是我们想要的。

工作流程摘要

现在工作流程如下:

git clone --recursive git@github.com:surevine/metre- 克隆存储库并检出HEADmaster

git checkout foo- 检出 foo 分支或提交 - 并将子模块切换到它们对 foo 的提交。

git submodule update --init --recursive --remote-沿跟踪分支递归更新所有--remote子模块。如果没有,它会将子模块的工作目录重置为父模块的“正确”提交。

最后,您可以:

git config submodule.recurse true- 告诉 git 大多数命令应该以递归方式执行,特别是git pull

鏂囩珷鏉ユ簮锛�https://dev.to/dwd/git-submodules-revisited-1p54
PREV
API 中的版本控制
NEXT
螺丝和锤子:热爱问题,而不是你的解决方案。