Git子模块
Git 子模块(Git submodules)允许你将 git repo 保留为另一个 git repo 的子目录。Git 子模块只是在特定时间快照上对另一个 repo 的引用。Git 子模块使 Git repo 能够合并和跟踪外部代码的版本历史。
Git子模块
添加子模块
通过下列命令,可以将在一个已存在的 Git 仓库添加为当前工作的仓库的子模块:
1 | git submodule add <repo url> [submodule path] |
例如,在一个 Hexo 博客仓库下添加一个主题仓库 NexT:
1 | git submodule add https://github.com/wylu/hexo-theme-next themes/next |
默认情况下,如果没有指定子模块存放路径,子模块将会放到一个与仓库同名的目录中。如果你想要放到其他地方,那么可以在命令结尾添加一个不同的路径,本例中子模块将会 clone 到 "themes/next" 目录下。
命令执行完成后,会在当前工作仓库根目录下生成 .gitmodules 文件,内容如下:
1 | [submodule "themes/next"] |
该文件保存了项目 URL 与已经拉取的本地目录之间的映射,如果有多个子模块,该文件中就会有多条记录。要重点注意的是,该文件应像 .gitignore 文件一样受到(通过)版本控制,和该项目的其他部分一同被拉取推送。有了映射关系,克隆该项目的人就知道去哪获得子模块了。
添加子模块完成后,当在父仓库时,Git 仍然不会跟踪 submodule 的文件, 而是将它看作该仓库中的一个特殊提交。
推送到远程仓库后,远程仓库中 submodule 会和指定的 commit 关联起来。如果需要指定分支,可以在 ".gitmodules" 文件中加上 branch 配置,如 branch = develop
。
克隆含有子模块的项目
接下来我们将会克隆(clone)一个含有子模块的项目。 当你在克隆这样的项目时,默认会包含该子模块目录,但其中还没有任何文件,你需要执行两个命令以拉取子模块:
1 | git submodule init |
git submodule init
用来初始化本地配置文件,而 git submodule update
则从子项目中抓取所有数据并检出父项目中列出的合适的提交。
或者:
1 | git clone --recursive <parent repo url> |
删除子模块
把子模块从版本控制系统中移除
1
git rm --cached <submodule path>
删除子模块目录
1
rm -rf <submodule path>
编辑 ".gitmodules",移除相应 submodule 节点内容
编辑 ".git/config",移除相应 submodule 配置
如果有 ".git/modules" 目录,还应删除其下的相应子模块的目录
以上面的 NexT 子模块为例:
1 | git rm --cached themes/next |
然后删除 ".gitmodules" 中如下内容:
1 | [submodule "themes/next"] |
最后删除 ".git/config" 中如下内容:
1 | [submodule "themes/next"] |
要把此次修改同步到远程库,还需要 push 一下。