' git submodule init'有什么意义?

时间:2017-06-05 10:02:31

标签: git git-submodules rationale

背景

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

git submodule init
git submodule update

在此用法中,git submodule init似乎只做了一件事:使用.git/config中已有的信息填充.gitmodules

有什么意义?

无法git submodule update只使用.gitmodules中的信息?这样可以避免:

  • 不必要的命令(git submodule init);和
  • 不必要的数据重复(.gitmodules内容到.git/config)。

问题

或者:

  • 我不知道git submodule init的用例(在这种情况下,请赐教!);或者
  • git submodule init是可以在Git中弃用的,没有任何伤害。

其中哪一项属实?

2 个答案:

答案 0 :(得分:33)

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

如果有人喜欢我的回答,请用英语纠正我的错误。

附加两个工作流演示。

工作流程1:子模块是多个项目使用的库。

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

你刚刚克隆了我的项目"。

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

其结构表面如下 enter image description here

.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

这意味着"准备从example.com/demo"更新lib1和lib2;。
此时,lib1和lib2目录为空 您可以使用一个命令克隆和检出lib1和lib2。

git submodule update

现在您可以在没有导入错误的情况下重构code1.js 子模块只是对某些提交的引用。因此,当您想要将库更新为新版本时,您必须更新引用。您可以通过以下命令来完成。

git submodule update --remote

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

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

我是这个的粉丝。

你克隆"主项目"。

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

其结构表面如下 enter image description here

您可以看到名为" shared"的目录。此工作流程中有一条规则:如果要在项目中使用主项目的共享代码,则必须将项目创建为主项目的子模块。
我喜欢将实体类放在共享目录中,如下所示。

enter image description here

回到子模块工作流程,.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

这次你要重构主项目共享目录中的一些代码,你知道只有sub-project1和sub-project2引用共享代码,这意味着你不需要克隆和签出子-project3和sub-project4。所以你只需运行以下命令。

git submodule init sub-project1 sub-project2

就像我在workflow1中提到的那样,你需要运行下面的命令来克隆和检查它们。

git submodule update

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

如果有人喜欢我的回答,请用英语纠正我的错误。

答案 1 :(得分:13)

阅读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