1.背景
面对比较复杂的项目,我们有可能会将代码根据功能拆解成不同的子模块。主项目对子模块有依赖关系,却又并不关心子模块的内部开发流程细节。
2.submodule的使用
2.1创建submodule
git submodule add <submodule_url>
此时项目仓库中会多出两个文件:.gitmodules
和 project-sub-1
。
前者的内容是子模块的相关信息;而后者那个文件夹,实际上保存的是子模块当前版本的版本号的代码。
.gitmodules文件内容
[submodule "project-sub-1"]
path = project-sub-1
url = https://github.com/username/project-sub-1.git
如果此前项目中已经存在 .gitmodules
文件,则会在文件内容中多出上述三行记录。
事实上,此时在 .git/config
文件中也会多出一些信息,在 .git/modules
文件夹下也会多出一份内容。
2.2.获取submodule
上述步骤在创建子模块的过程中,会自动将相关代码克隆到对应路径,但对于后续使用者而言,对于主项目使用普通的 clone
操作并不会拉取到子模块中的实际代码,完成后 project-main/project-sub-1
文件夹是空的。
#递归地将项目中所有子模块的代码拉取
git clone git@gitlab.raina.tech:eda-team/database/Thor.git --recurse-submodules
#如果已经拉取代码 可以根据主项目的配置信息,再次拉取更新子模块中的代码
git submodule init
git submodule update
#如果主项目记录的子模块版本还没有变化,需要拉取子模块中的代码
git submodule foreach 'git pull origin master'
2.3.删除子模块
# 卸载一个子模块,如果添加上参数 --force,则子模块工作区内即使有本地的修改,也会被移除
git submodule deinit project-sub-1
git rm project-sub-1
git commit -m "delete submodule project-sub-1"
执行 git submodule deinit project-sub-1 命令的实际效果,是自动在 .git/config 中删除了以下内容:
[submodule "project-sub-1"]
url = https://github.com/username/project-sub-1.git
执行 git rm project-sub-1 的效果,是移除了 project-sub-1 文件夹,并自动在 .gitmodules 中删除了以下内容:
[submodule "project-sub-1"]
path = project-sub-1
url = https://github.com/username/project-sub-1.git
此时,主项目中关于子模块的信息基本已经删除(虽然貌似 .git/modules 目录下还有残余):
➜ project-main git:(master) ✗ gs
位于分支 master
您的分支与上游分支 'origin/master' 一致。
要提交的变更:
(使用 "git reset HEAD <文件>..." 以取消暂存)
修改: .gitmodules
删除: project-sub-1