'git submodule init'有什么意义?

sam*_*per 44 git rationale git-submodules

背景

要填充存储库的子模块,通常会调用:

git submodule init
git submodule update
Run Code Online (Sandbox Code Playgroud)

在这种用法中,git submodule init似乎只做一件事:填充.git/config已经存在的信息.gitmodules.

那是什么意思?

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

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

或者:

  • 有用例git submodule init我不知道(在这种情况下,请赐教!); 要不然
  • git submodule init 可以在Git中弃用而没有任何伤害.

以下哪一项是正确的?

Nig*_*iri 40

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

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


附加两个工作流程演示.

Workflow1:子模块是几个项目使用的库.

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

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

git clone https://example.com/demo/my-project
Run Code Online (Sandbox Code Playgroud)

它的结构表面如下.
在此输入图像描述

.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
Run Code Online (Sandbox Code Playgroud)

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

git submodule init lib1 lib2
Run Code Online (Sandbox Code Playgroud)

现在让我们看看内容 .git/config

...
[submodule "lib1"]
    active = true
    url = https://example.com/demo/lib1
[submodule "lib2"]
    active = true
    url = https://example.com/demo/lib2
Run Code Online (Sandbox Code Playgroud)

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

git submodule update
Run Code Online (Sandbox Code Playgroud)

现在您可以重构code1.js而不会导致导入错误.
子模块只是对某些提交的引用.因此,当您想要将库更新为新版本时,您必须更新引用.您可以通过以下命令执行此操作.

git submodule update --remote
Run Code Online (Sandbox Code Playgroud)

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

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

我是这个的粉丝.

你克隆"主项目".

git clone https://example.com/demo/main-project
Run Code Online (Sandbox Code Playgroud)

它的结构表面如下.
在此输入图像描述

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

在此输入图像描述

回到子模块工作流程,.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
Run Code Online (Sandbox Code Playgroud)

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

git submodule init sub-project1 sub-project2
Run Code Online (Sandbox Code Playgroud)

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

git submodule update
Run Code Online (Sandbox Code Playgroud)

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

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


sam*_*per 17

读取git submodule 文档,存在其表面上证明存在一个用例git submodule init作为一个独立的命令.

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

git submodule init
vim .git/config # Alter submodule URL as desired, without changing .gitmodules
                # or polluting history.
git submodule update
Run Code Online (Sandbox Code Playgroud)

  • 例如,当子模块很大并且由于其他原因您已经在本地获得它时。`git config -f .gitmodules submodule.biglib.url=/path/to/it` 比编辑文件更容易,当你满意时,`git submodule update --init` 比两步更容易默认值。 (2认同)