git submodule

本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2021-02-26

参考:Git中submodule的使用Git Submodule使用完整教程

git submodule 用来建立当前项目与子模块之间的依赖关系,使父模块与子模块能够保持各自独立的版本控制。

创建

# 本地子模快的目录为可选 不设置 默认在当前目录下创建子模块
git submodule add <子模块git仓库地址> <复制到本地的子模块目录>

执行之后,项目中会多出两个文件 .gitmodules 和 创建的子模块目录

其中 .gitmodules的内容大致为

[submodule 'sub-pro']
path = sub-pro
url = github.com/xxx/sub-pro

这样,将“相当于”在项目中复制进来了子模块的整个文件,只不过优点是,当子模块变动时,不需要再重新复制,只需要更新就行了,父子模块各自独立。

此时可以使用 add 和 commit 提交一次,表示引入了某个子模块。提交后,在主项目仓库中,会显示出子模块文件夹,并带上其所在仓库的版本号

后续使用者该如何获取

当后续使用者使用 git clone github.com/xxx/parent-pro时,并不会将子模块的实际代码也“复制”到当前 clone 的目录中,需要带上额外的参数才可以。

git clone github.com/xxx/parent-pro --recurse-submodules

或者使用不带参数的 git clone 命令 clone 父模块后,再使用如下命令将子模块“复制”下来。

# 会根据主项目的配置信息,拉取更新子模块中的代码。
git submodule init 
git submodule update

子模块内容的更新

1、子模块有未跟踪的内容变化

通常是在开发环境中,直接修改子模块文件夹中的代码导致的。

需要使用 cd sub-pro 切换到子模块目录下,进行 add 、 commit 、push 进行提交。

2、子模块有版本变化

当有第1中的场景被完成后,子模块有版本变化的时候,在主项目中使用 git status 查看仓库状态时,会显示子模块有新的提交:

# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   sub-pro/xxx (new commits)  这一行
#

在这种情况,直接使用 add 、 commit 、push 进行提交到主项目中,实际改动的就是 子模块 的相关文件。

通常当子项目更新后,主项目修改其所依赖的版本时,会产生类似这种情景的 commit 提交信息。

3、子模块远程有更新

通常来讲,主项目与子模块的开发不会恰好是同时进行的。通常是子模块负责维护自己的版本升级后,推送到远程仓库,并告知主项目可以更新对子模块的版本依赖。

之前曾经提到,主项目可以使用 git submodule update 更新子模块的代码,但那是指 当前主项目文件夹下的子模块目录内容 与 当前主项目记录的子模块版本 不一致时,会参考后者进行更新。

但如今这种情况下,后者 当前主项目记录的子模块版本 还没有变化,在主项目看来当前情况一切正常。

此时,需要让主项目主动进入子模块拉取新版代码,进行升级操作。

需要使用 cd sub-pro 切换到子模块目录下,进行 git pull origin master 操作。

当主项目的子项目特别多时,可能会不太方便,此时可以使用 git submodule 的一个命令 foreach 执行:git submodule foreach 'git pull origin master'

将代码拉取下来后,才切换到主项目 cd .. 进行 add commit push 提交到主项目的git仓库中。

删除子模块

# 删除 对于子模块的依赖
git submodule deinit sub-pro
# 删除 子模块的文件夹
git rm sub-pro 

这样就等同于删掉了 .gitmodules 文件中的对子模块的相关配置。

然后进行主项目代码的提交 add commit push,将删除相关的代码 同步到远程仓库中。