经过一些研究,我正在回答我自己的问题,这可能对其他人有帮助:
理解 git 子模块是一件很痛苦的事,但是一旦你明白了,一切都开始变得有意义了!
以下帖子显示:
- 添加子模块并让其他人与您的子模块同步。
- 更新子模块并让其他人与您的子模块同步。
- 删除子模块并让其他与您的子模块同步。
- 更新已移除的子模块。
添加子模块
git 子模块添加 -b
.gitmodules 中的条目(名称、路径、url、分支)通过
下载相应的子模块
git submodule update --init
这做了三个重要的事情,前两个对用户是隐藏的:
使用额外的条目(子模块)更新 .git/config
在 .git/modules 下以裸形式下载存储库。这意味着,.git 中有 .git。
将 .git/modules 中的 git 子模块检出到父目录中。
现在,在第 2 天,提交子模块的提交者意识到,他应该将子模块更改为其他提交,而不是 HEAD。所以,他会去他的本地存储库,然后去子模块路径,然后通过简单地调用来签出他想要的提交
git checkout <hash>
cd <parent dir>
git submodule status
此时,git子模块状态仍然没有显示新的哈希。新的散列仅在更改进行时可见。现在,提交者只需要暂存(添加)、提交和推送更改,以便所有其他开发人员都可以看到它。
更新添加的子模块
在第 3 天,其他开发人员只需调用命令即可更新他们的存储库
git pull # this is to get the latest commit of the parent git repository.
git submodule update --force # update the submodule with latest hash
基本上,这里的要点很简单:子模块不会做出反应,除非它被告知这样做。只是做 git pull,不会更新 git 子模块。开发人员可以继续处理他们的本地子模块,而不是“永远”将它们同步到服务器上的子模块。子模块更新将在显式调用 git submodule update 命令时发生。
删除子模块
现在,在第 4 天,提交者决定完全删除 git 子模块。这里的步骤也不简单,因为没有什么叫做 git submodule rm 应该等同于 git submodule add。只有遵循以下顺序才能做到这一点:
git submodule deinit submodulename
这会删除 .git/config 条目。
这将清除子模块目录!执行此命令后,您将在 submdoule 目录中看不到任何内容。
但是.git/modules下子模块的内容还是可以的
因此这里的 git status -u 仍然会显示 Everyting 是最新的!
所以显示删除,
git rm submodulepath
此时 git status 将返回 .gitmodules 已更改(子模块已被删除)并且子模块路径已被删除。提交并推送更改。
使用已删除的子模块进行更新
在第 5 天,开发人员希望像使用 git submodule update 一样“自动”删除子模块。所以他们首先做一个 git pull,它成功地删除了 git 子模块的所有索引
git submodule status # shows nothing
但是,.git/config 仍然包含有效的子模块条目,并且子模块文件夹及其所有内容和 .git/submodules 下的裸存储库都在那里!没有删除它们的命令。所有这些都必须通过手动明确删除..(如果我错了,请纠正我)