子模块
有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目。 也许是第三方库,或者你独立开发的,用于多个父项目的库。 现在问题来了:你想要把它们当做两个独立的项目,同时又想在一个项目中使用另一个。在其他的博客中也介绍过两个方法,现在顺便介绍另一种更加优雅的方法---子模块
添加子模块
我们首先将一个已存在的 Git 仓库添加为正在工作的仓库的子模块。 你可以通过在 git submodule add
命令后面加上想要跟踪的项目的相对或绝对 URL 来添加新的子模块。 在本例中,我们将会添加一个名为 “DbConnector” 的库。
$ git submodule add https://github.com/chaconinc/DbConnector
Cloning into 'DbConnector'...
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 11 (delta 0), reused 11 (delta 0)
Unpacking objects: 100% (11/11), done.
Checking connectivity... done.
默认情况下,子模块会将子项目放到一个与仓库同名的目录中,本例中是 “DbConnector”。 如果你想要放到其他地方,那么可以在命令结尾添加一个不同的路径。
当我们添加子模块以后,会多一个.gitmodules
文件
//指定子模块的名字
[submodule "DbConnector"]
//自定子模块的存放路径,这里是同级目录下的DbConnector目录
path = DbConnector
//子模块的clone地址
url = https://github.com/chaconinc/DbConnector
克隆含有子模块的项目
当我们直接git clone
的时候,会显示子模块的目录,但是文件目录是空的,必须运行两个命令:git submodule init
用来初始化本地配置文件,而 git submodule update
则从该项目中抓取所有数据并检出父项目中列出的合适的提交
不过还有更简单一点的方式。 如果给 git clone
命令传递 --recurse-submodules
选项,它就会自动初始化并更新仓库中的每一个子模块, 包括可能存在的嵌套子模块。
$ git clone --recurse-submodules https://github.com/chaconinc/MainProject
如果你已经克隆了项目但忘记了 --recurse-submodules
,那么可以运行 git submodule update --init
将 git submodule init
和 git submodule update
合并成一步。如果还要初始化、抓取并检出任何嵌套的子模块, 请使用简明的 git submodule update --init --recursive
。
子模块更新与提交
子模块与我们的普通的git仓库没有什么区别,当我们需要更新或者提交代码的时候,直接进入对应的目录即可。
额外,如果我们使用Android Studio自带的管理工具,也可以很轻松的使用子模块这个特性
常见问题
fatal: You are on a branch yet to be born
删除与.git modules/目录下的子模块具有相同路径的文件夹,如果一直报错,请参考下面的,使用-b 分支名
参数去指定准备checkout出来的分支
The following paths are ignored by one of your .gitignore files
The following paths are ignored by one of your .gitignore files:
SDK
hint: Use -f if you really want to add them.
hint: Turn this message off by running
hint: "git config advice.addIgnoredFile false"
fatal: Failed to add submodule 'SDK'
添加-f参数
git submodule add -b 分支名 --name 目录名 -f git地址 目录名