本节课我们学习下让一个项目中依赖另外一个子项目
有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目。 也许是第三方库,或者你独立开发的,用于多个父项目的库。 现在问题来了:你想要把它们当做两个独立的项目,同时又想在一个项目中使用另一个。
Git 通过子模块来解决这个问题。 子模块允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。 它能让你将另一个仓库克隆到自己的项目中,同时还保持提交的独立。
添加子模块
比如我们已经创建好了一个仓库,现在需要对它添加子模块
# 在主项目中添加子项目,URL 为子模块的仓库路径,path 为该子模块存储的目录路径
git submodule add [URL] [Path]
初始化子模块
前面只是在Git主项目中添加了子模块,并没有拉取子模块的代码。我们需要通过以下命令拉取代码。
注意,当主项目克隆git clone
后,也是不包含子模块代码的,也需要运行下面命令。
# 初始化子模块
git submodule init
# 子模块更新代码
git submodule update
# 或者一步到位,下面的代码包含了上面两行代码的功能
git submodule update --init
或者直接对主项目使用下面命令,一步到位的拉取子模块代码。
git clone --recurse-submodules [url]
更新子模块
在主项目目录中,运行update命令。这个命令会拉取远程的子模块提交到本地。
# 与主仓库中的子模块代码同步
git submodule update
# 与子仓库中代码同步(同步所有的子模块)
git submodule update --remote
# 指定需要同步的子模块
git submodule update --remote xxx
或者,可以进入对应的子模块,运行pull命令
# 在子模块目录下运行
git pull
上面两种方法,同步的都是子模块的master
分支上代码。如果要同步某个开发分支呢。需要通过.gitmodules
来同步。
git config -f .gitmodules submodule.[submodule-name].branch [branch-name]
# 在子模块目录下运行
git pull
推送代码
如果我们在主项目中提交并推送但并不推送子模块上的改动,其他尝试检出我们修改的人会遇到麻烦, 因为他们无法得到依赖的子模块改动。那些改动只存在于我们本地的拷贝中。为了确保这不会发生,你可以让 Git 在推送到主项目前检查所有子模块是否已推送。
# 主项目在推送代码时,会检查所有子项目子模块是不是都已经推动了
git push --recurse-submodules=check
如果提示失败,那么需要我们去每一个子模块中先push
代码,然后再在主项目中push
代码。
从子目录升级到子模块
一般来说,某个公共代码,我们都会先作为一个子目录来维护。之后发现能通用时,才会升级为一个子模块。这种升级需要走一定的步骤。 首先,你需要先取消之前子目录的暂存。
git rm -r [xxxxx]
然后才能添加对应名字的子模块
git submodule add [submodule-name]