有时候,一个项目需要使用另一个 Git 仓库,也许是第三方库,或者独立的项目,那如何让所有的 Git 仓库在这一项目目录里共存呢? Git submodule 便派上了用场。
什么是 Git submodule
Git submodule
即 Git 子模块,子模块允许将一个 Git 仓库作为另一个 Git 仓库的子目录。同一个项目目录,但是独立的 git 记录和提交。
如何新建 Git submodule
git submodule add <子模块git地址> <存放的文件路径以及文件名>
如果需要指定子模块某分支的话(需要 Git 1.8.2+)
git submodule add -b <子模块分支> <子模块git地址> <存放的文件路径以及文件名>
然后git add . && git commit
保存记录。
执行 tree -a
可以查看当前 repoA
目录结构变化如下
.
├── .git
│ ├── HEAD
│ ├── branches
│ ├── config
│ ├── ...
│ ├── modules # git记录新增modules
│ │ └── plugins
│ │ └── repoB
│ │ ├── HEAD
│ │ ├── branches
│ │ ├── config
│ │ ├── ...
│ │ └── refs
│ └── refs
├── .gitmodules #新增
├── README.md
└── plugins # 新增子模块目录
└── repoB
├── .git # 子模块git记录
└── README.md
如何克隆含有子模块的项目
如果第一次克隆,使用--recurse-submodules
参数
git clone --recurse-submodules <git仓库地址>
在已克隆的项目里克隆子模块
- 正常克隆仓库
git clone <git 仓库地址>
- 当前项目目录执行
git submodule init
,该命令会初始化本地配置文件 - 执行
git submodule update
检查该项目子模块所有的更新
另外 2和3可以直接简写为 git submodule update --init --recursive
如何更新 Git submodule
子模块修改后需要更新主仓库
主仓库和子模块的更新和正常使用 git项目一致,这里主要说明一下子模块的修改之后主仓库仍然需要提交更新之后的 submodule,提交到git记录里。
下图对子模块进行修改提交,注意git submodule 里指向的只是一个 commit SHA 值,需要 checkout 到你需要提交到的分支。
之后需要再次提交主仓库的修改
子模块有更新同步到本地
主项目直接 git pull
即可(但是需要注意 submodule 的在一个修改后确定的的分支上)。
如何彻底删除 Git submodule
相当复杂如下所示:
-
移除目录
git rm --cache <git submodudle 所在目录>
-
rm -rf <git submodudle 所在目录>
-
删除
.gitmodules
或者 编辑.gitmodules
删除该文件里该 submodule 的记录[submodule "plugins/repoB"] path = plugins/repoB url = git@github.com:paddingme/repoB.git branch = dev
-
修改
./git/config
中该submodule相关内容[core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true ignorecase = true precomposeunicode = true [remote "origin"] url = git@github.com:paddingme/repoA.git fetch = +refs/heads/*:refs/remotes/origin/* [branch "main"] remote = origin merge = refs/heads/main [submodule "plugins/repoB"] # 删除这里 url = git@github.com:paddingme/repoB.git # 删除 active = true # 删除
-
删除 .git 文件夹中的相关子模块文件 如
rm -rf .git/modules/plugins/repoB/
-
git add .&& commit
-
最后最好再
git submodule sync
下。
这里就不演示了,累了。
总结
如上,不得不说 git submodule 用起来有点复杂,有一定的学习成本,在使用 git submodule 时记住如下两条,会让情况变得好一些,再者就是常回来看看这篇文章情况可能还会更好一点。
- 常用
git status
查看当前目录状态 - 确认 submodule 是否在正确的分支上
References
本文同步发布于 padding.me/git-submodu…