Git中的submodule操作

环境

  • 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

b7ea17408142d0b0c1057f2c3e830b97.png

git submodule

然后,将上面创建好的项目克隆到本地

git clone https://github.com/xugaoxiang/gitDemo.git

4769eca31d42a8700c80db77d0434534.png

git submodule

添加子模块

现在开始来添加子模块,这里以 yolov5 为例,将其作为子模块放在 gitDemo 项目里

git submodule add https://github.com/ultralytics/yolov5.git

7b76550a99297ab791dec1c715284e0d.png

git submodule

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

09e60aaff4a78f188dff7e1cdaa8cfb5.png

git submodule

通过 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)

d26067f0c3f171cea9ea45217940f550.png

git submodule

可以看到添加到 gitDemo 项目中的 yolov5 提交版本号是 621b6d5ba80707ca98242dd7c71d738e5594b41e

这时候就可以将子模块提交到 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 了

a6ae86ef8b426351ef304f2df3a0f859.png

git submodule

克隆带有子模块的工程

克隆项目后,子模块目录默认是空的,需要我们在项目根目录下执行如下命令完成子模块的下载

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

19d275159a18df67dbd76b497d6baa53.png

git submodule

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

99ef7a9095e9caefda1c211ae27a4c1d.png

git submodule

接下来,删除 .git 文件夹中的相关子模块文件,如这里的 yolov5

最后就可以git commit 和 git push 了