子模块
有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目。 也许是第三方库,或者你独立开发的,用于多个父项目的库。 现在问题来了:你想要把它们> 当做两个独立的项目,同时又想在一个项目中使用另一个。
我们举一个例子。 假设你正在开发一个网站然后创建了 Atom 订阅。 你决定使用一个库,而不是写自己的 Atom 生成代码。 你可能不得不通过 CPAN 安装或 Ruby > gem 来包含共享库中的代码,或者将源代码直接拷贝到自己的项目中。 如果将这个库包含进来,那么无论用何种方式都很难定制它,部署则更加困难,因为你必须确保每> 一个客户端都包含该库。 如果将代码复制到自己的项目中,那么你做的任何自定义修改都会使合并上游的改动变得困难。
Git 通过子模块来解决这个问题。 子模块允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。 它能让你将另一个仓库克隆到自己的项目中,同时还保持提交的独> 立。
开始使用
创建子模块
子模块创建指令参考如下:
|
|
子模块在创建后会生成一个 .gitmodules 文件,该文件包含子模块的配置信息。
|
|
如果有多个子模块,该文件中就会有多条记录。 要重点注意的是,该文件也像 .gitignore 文件一样受到版本控制。 它会和该项目的其他部分一同被拉取推送。
克隆含有子模块的项目
当你需要克隆一个包含子模块的项目时,推荐你使用如下命令 (它就会自动初始化并更新仓库中的每一个子模块, 包括可能存在的嵌套子模块):
|
|
当你在克隆这样的项目时,如果你忘记了使用 --recurse-submodules,那么默认只会包含该子模块目录,但其中还没有任何文件。
需要执行如下命令进行初始化并更新子模块:
|
|
或者将两者命令合并:
|
|
如果还要初始化、抓取并检出任何嵌套的子模块,建议使用如下指令:
|
|
更新子模块
默认情况下,git pull 命令会递归抓取子模块的更改。但是它 不会更新 子模块。它仅会显示子模块 “已修改”,且 “有新的提交”。
为了完成更新,推荐运行如下指令:
|
|
修改子模块 Remote 或 Branch
子模块的 .gitmodules 文件中记录了子模块的远程仓库和分支。
可以修改该文件,然后执行如下指令来更新子模块的远程仓库和分支:
|
|
删除子模块
当你需要删除子模块时,可参考如下指令:
|
|