参考链接:
Git Submodules 介绍(通俗易懂,总结了工作完全够用的 submodule 命令)
cd到主项目,执行:
git submodule add ...(另一仓库地址,即git clone时后面那串东西)
下面可以指定 submodule 放到哪个子文件夹
git submodule add ...(另一仓库地址) [(可选,submodule下载的路径)]
(1) 先 git clone 主项目仓库并进入主项目文件夹,这时候 submodule 的文件夹都是空的。
(2) 执行
git submodule init [submodule的文件夹的相对路径]
(3) 执行
git submodule update [submodule的文件夹的相对路径]
这就按需 clone了submodule。
跨团队协作某个主项目时,一些其它团队的 submodule 没必要安装,就不必执行 init 和update。
git submodule update --init [submodule的文件夹的相对路径]
–init 和 [submodule的文件夹的相对路径] 的位置不可以调换。
(1) 先 git clone 主项目仓库,这时候 submodule 的文件夹都是空的。
(2) 执行
git submodule init
(3) 执行
git submodule update
只要不写 [submodule的文件夹的相对路径],那么就一次性检查该主项目的所有submodule,都拉下来。
git submodule update --init
git clone --recurse-submodules [主项目Git仓库地址]
(1) 项目很大参与开发人员多的时候,需要将各个模块文件进行抽离单独管理。
(2) 使用 git submodule 来对项目文件做成模块抽离,抽离出来的文件可单独成为一个 git 仓库。
整个主项目对抽离出来的子项目(子模块)有依赖关系,却又并不关心子项目(子模块)的内部开发流程细节。
(3) 代码如果全员可见,可以做成分支进行管理;如果代码不可见,可以创建为子仓库(独立一个git 仓库);子仓库管理模块代码,主仓库定时更新。
(4) 简单理解:项目工程为一个仓库;模块为一个仓库;主仓库操作 git module 命令来使用这个模块子仓库;主项目,子模块可由不同的开发人员维护。
如果某些文件,在项目A和项目B中都会用到,例如组件库,那么这些文件可以作为 submodules 来管理,减少重复代码。(当然,该场景下npm包是另一解决方案,你需要选择一种方案。)
如果一个大项目是一个大 Git 仓库,需要统一编译,不同的模块由不同团队维护,放在同一个 Git 仓库有诸多难处。
例如多个团队的 MR 混在一起、权限难以区分等。这种情况即使公司内网 Git 权限做的足够精细,仓库管理员的学习成本也会很高,很难深度使用这种高级功能。
为了解决多团队维护的难题,Git Submodules 也能大展身手,它可以让每个团队负责的模块就是一个 Git 仓库,这些 Git 仓库都被包含在同一个主 Git 项目下。(当然,微前端、微服务是另一种解决方案,你需要选择一种方案。)
有2个概念:主项目、submodule(子模块)。这两者各自都是完整的 Git 仓库。
如何让一个 Git 仓库变为另一个 Git 仓库的 submodule
(1) 创建 Git 仓库 A。
(2) 创建 Git 仓库 B。
(3) 在 Git 仓库 A 中,通过
git submodule add ...(仓库B的地址,即git clone时后面那串东西)
可以把仓库 B 当作仓库 A 的 submodule,此时 A 就成了主项目。
B 也可以做 A 的主项目,在仓库B执行
git submodule add ...(A地址)
因为在建立父子关系前,二者都是完整 Git 仓库,没有差异。
(1) 执行操作后,会在当前父项目下新建个文件夹,名字就是 submodule 仓库的名字。这个文件夹里面的内容,是 submodule 对应 Git 仓库的完整代码。
(2) 如果希望换个名字,或者换个路径(例如放在某个更深的目录下),也是允许的,需要后面增加个路径参数,例如
git submodule add ...(仓库地址) src/B(你希望 submodule 位于的文件夹路径)
关系保存在主项目的 Git 仓库中。
被当作 submodule 的 Git 仓库,其实不知道自己变成了 submodule,它更不知道爸爸们有谁。(意思是,当你打开某个被当作 submodule 的 Git 仓库首页时,或者拉下这个仓库时,没有任何痕迹表明它是个submodule。因为父子信息不存在这里,只存在爸爸那里。)
.gitmodules 文件
父子关系的信息保存在主项目的 .gitmodules 文件,如果不是新加 submodule,这个文件通常不必改变了,因为信息比较固定。
主项目还保存了对应 submodule 的版本号(commit id),没有冗余存储 submodule 的代码
可以看到,这其实是个跳转到另一个仓库的链接,指明了具体的 commit id。