'git submodule init' 有什么意义?

What is the point of 'git submodule init'?

背景

要填充存储库的子模块,一个 typically invokes:

git submodule init
git submodule update

在这种用法中,git submodule init 似乎只做一件事:用 .gitmodules.

中已有的信息填充 .git/config

这样做有什么意义?

不能git submodule update简单地使用来自.gitmodules的信息吗?这将避免:

问题

或者:

以下哪个是正确的?

阅读 git submodule documentation,其中 一个表面上证明 git submodule init 作为独立命令存在的用例。

如果克隆了存储库的用户希望对子模块使用不同于上游存储库指定的 URL,则该用户可以:

git submodule init
vim .git/config # Alter submodule URL as desired, without changing .gitmodules
                # or polluting history.
git submodule update

假设存储库有 10 个子模块,而您只对其中的两个子模块感兴趣。在这种情况下,您可能希望不时从远程存储库中仅获取这两个子模块的更新。 git init 对此效果很好,因为一旦您对这两个子模块执行命令 git initgit submodule update --remote 仅适用于它们。


附加了两个工作流演示。

Workflow1:子模块是多个项目使用的库。

我认为这是常见的用例之一。

您刚刚克隆了 "my-project"。

git clone https://example.com/demo/my-project

它的表面结构如下。

.gitmodules的内容

[submodule "lib1"]
    path = lib1
    url = https://example.com/demo/lib1
[submodule "lib2"]
    path = lib2
    url = https://example.com/demo/lib2
[submodule "lib3"]
    path = lib3
    url = https://example.com/demo/lib3
[submodule "lib4"]
    path = lib4
    url = https://example.com/demo/lib4

您想重构引用 lib1 和 lib2 的代码 code1.js,这意味着您不需要克隆和签出 lib3 和 lib4。所以你只需 运行 下面的命令。

git submodule init lib1 lib2

现在让我们看看.git/config

的内容
...
[submodule "lib1"]
    active = true
    url = https://example.com/demo/lib1
[submodule "lib2"]
    active = true
    url = https://example.com/demo/lib2

这意味着类似于 "Ready to update lib1 and lib2 from example.com/demo"。

此时,lib1 和lib2 目录是空的。您可以使用一个命令克隆和检出 lib1 和 lib2:

git submodule update

现在您可以重构 code1.js 而不会出现导入错误。

子模块只是对某些提交的引用。所以当你想将库更新到新版本时,你必须更新引用。您可以通过以下命令完成。

git submodule update --remote

现在你可以看到只初始化你需要的子模块是多么有用了。

工作流程2:每个子模块都是一个项目,一个大的顶级项目包含它们。

我是这个的粉丝。

你克隆了"main-project".

git clone https://example.com/demo/main-project

它的表面结构如下。

您可以看到一个名为 "shared" 的目录。这个工作流程有一个规则:如果你想在你的项目中使用主项目的共享代码,你必须将项目创建为主项目的子模块。

我喜欢将实体 类 放在共享目录中,如下所示。

回到子模块工作流程,.gitmodules 的内容如下。

[submodule "sub-project1"]
    path = sub-project1
    url = https://example.com/demo/sub-project1
[submodule "sub-project2"]
    path = sub-project2
    url = https://example.com/demo/sub-project2
[submodule "sub-project3"]
    path = sub-project3
    url = https://example.com/demo/sub-project3
[submodule "sub-project4"]
    path = sub-project4
    url = https://example.com/demo/sub-project4

这次你想重构主项目共享目录下的一些代码,你知道只有子项目1和子项目2引用共享代码,这意味着你不需要克隆和签出子项目-项目 3 和子项目 4。所以你只需 运行 下面的命令。

git submodule init sub-project1 sub-project2

就像我在工作流程 1 中提到的那样,您需要 运行 下面的命令来克隆和检出它们。

git submodule update

在这种情况下我会 git submodule update --remote 吗?或者我什至需要初始化和更新子模块来重构共享目录中的代码?是的,因为在重构共享代码后,您必须 运行 在子模块中进行测试,并且如果在重构时提交了子模块的任何更新并将其推送到远程存储库,那么您需要通过 git submodule update --remote 获取它.