为什么要用子模块
痛点
在我们开发项目的时候可能会遇到下面这个问题:在你的项目中使用另外一个项目,也许这个是一个第三方开发的库或者是你独立开发和并在多个父项目中使用的。简单的说就是A同学开发的一个模块,被B、C…同学共同调用(使用),可能就形成了如下的这种关系。
这个场景下一个常见的问题产生了:你想将两个项目单独处理但是又需要在其中一个中使用另外一个。
解决方案
这种问题,Git 已经帮我们有了处理方案——子模块。
如何使用子模块
假如目前我们有两个仓库,module
(目标仓库)和 submodule
(子模块仓库)。
在现有的仓库中加入子模块
1 | git submodule add https://gitee.com/Hancoson/submodule.git submodule |
现在你就在项目
module
里的子目录下有了一个submodule
项目。如果你在加入子模块后立刻运行git status
,你会看到下面两项:1
2
3
4
5
6On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitmodules
new file: submodule查看
.gitmodules
文件1
2
3[submodule "submodule"]
path = submodule
url = https://gitee.com/Hancoson/submodule.git
如果你有多个子模块,这个文件里会有多个条目。很重要的一点是这个文件跟其他文件一样也是处于版本控制之下的,就像你的 .gitignore
文件一样。它跟项目里的其他文件一样可以被推送和拉取。这是其他克隆此项目的人获知子模块项目来源的途径。
- 提交增加的子模块到现有仓库的远程仓库
commit
方式和普通提交的方式相同。然后,module
仓库是这样的:
修改子模块
- 切换到要修改代码的子模块分支,修改对应代码,push(和普通仓库方式相同)
拉取服务器代码,并且合并到本地
module
(目标仓库分支)1
git submodule update --remote --merge
修改目标仓库,推送
克隆一个带子模块的项目
这里你将克隆一个带子模块的项目。当你接收到这样一个项目,你将得到了包含子项目的目录,但里面没有文件,如下:
submodule
目录存在了,但是是空的。你必须到 module
(目标仓库分支)根目录下运行两个命令:git submodule init
来初始化你的本地配置文件,git submodule update
来从那个项目拉取所有数据并检出你上层项目里所列的合适的提交:
1 | $ git submodule init |
现在你的 submodule
子目录就处于你先前提交的确切状态了。每次你从主项目中拉取一个子模块的变更都必须这样做 git submodule update
。
后续
子模块使用过程还需要大家自己多练习一下,主要的命令 git submodule *
.