环境
- windows 10 64-bit
- github
前言
子模块( submodule )是一个内嵌在 git 仓库(父工程)中的 git 仓库,有点儿拗口。通过子模块,可以将外部的仓库作为子目录放到自己的仓库中,既能方便的管理依赖,又可以保持依赖本身的独立性。
子模块将被记录在一个名叫 .gitmodules 的文件中,其中会记录子模块的相关信息
[submodule "module_name"] # 子模块的名称
path = file_path # 子模块在本仓库中文件的存储路径
url = repo_url # 子模块的远程仓库地址
前文我们介绍 基于YOLOv5和DeepSort的目标跟踪 时,它的代码仓库就是把 yolov5 作为子目录来进行管理
实践
本文在 github 平台上进行操作,其它基于 git 的管理平台也是类似的
新建项目
在 github 上创建一个新项目 gitDemo

然后,将上面创建好的项目克隆到本地
git clone https://github.com/xugaoxiang/gitDemo.git

添加子模块
现在开始来添加子模块,这里以 yolov5 为例,将其作为子模块放在 gitDemo 项目里
git submodule add https://github.com/ultralytics/yolov5.git

这时候的目录结构是这样的

通过 git status 查看当前状态
(base) PS C:\Users\Administrator\Desktop\gitDemo> git status
On branch main
Your branch is up to date with 'origin/main'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitmodules
new file: yolov5
可以项目目录下多了个文件 .gitmodules , 这个文件是用来保存子模块的信息,子模块是 yolov5
通过 git submodule 查看子模块
(base) PS C:\Users\Administrator\Desktop\gitDemo> git submodule
27a4736e968158063a87024be74534a560fc8e84 yolov5 (v5.0-438-g27a4736)

可以看到添加到 gitDemo 项目中的 yolov5 提交版本号是 27a4736e968158063a87024be74534a560fc8e84
这时候就可以将子模块提交到 gitDemo 中去了
(base) PS C:\Users\Administrator\Desktop\gitDemo> git commit -m "add submodule yolov5"
[main 739f379] add submodule yolov5
2 files changed, 4 insertions(+)
create mode 100644 .gitmodules
create mode 160000 yolov5
然后就可以开始推送了
git push origin main
完成后,就可以看到了 gitDemo 下的 yolov5 子模块了,这个子模块有点像超链接,点击后就直接进入了原版的 yolov5 了

克隆带有子模块的工程
克隆项目后,子模块目录默认是空的,需要我们在项目根目录下执行如下命令完成子模块的下载
git submodule init
git submodule update
或者
git submodule update --init --recursive
上面的方法,步骤繁多,比较麻烦,不推荐。可以直接在克隆的时候一起下载子模块,一气呵成,命令如下
git clone https://github.com/xugaoxiang/gitDemo.git --recursive
更新子模块
一般来说,子模块是不断在维护更新的,在我们自己的项目里,一般不会去改动子模块。但是如果想保持本地子项目与远程仓库版本一致,就需要去更新子模块至远程仓库的最新版
git submodule update --remote
需要注意的是,命令 git submodule update 是更新项目内子模块到最新版本
删除子模块
如果不再依赖子模块了,就可以将其删除了,步骤如下
# 删除子目录
git rm yolov5
然后修改 .gitmodules 将其中跟子模块相关的删除,如果是最后一个子模块的话,可以直接删除文件 .gitmodules

接着修改 .git/config,同样将对应子模块的信息删除

接下来,删除 .git 文件夹中的相关子模块文件,如这里的 yolov5
最后就可以git commit 和 git push 了