Core's ink

Back

Git Submodule 简明教程Blur image

有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目,也许是第三方库,或者你独立开发的,用于多个父项目的库。

现在问题来了:你想要把它们当做两个独立的项目,同时又想在一个项目中使用另一个。

Git 通过子模块来解决这个问题,子模块允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。 它能让你将另一个仓库克隆到自己的项目中,同时还保持提交的独立。

添加子模块#

添加一个远程仓库项目 https://github.com/Wu-yikun/Hydex 子模块到一个已有主仓库项目中。

代码形式是 git submodule add <url> <repo_name/folder_name>, 如下面的例子:

# Hydex 不存在则会先执行 clone,克隆到 Hydex 文件夹/指定 Hydex 文件夹
git submodule add https://github.com/Wu-yikun/Hydex Hydex
bash

主仓库会新增 .gitmodules 文件,用于记录子模块信息:

[submodule "Hydex"]
	path = Hydex
	url = https://github.com/Wu-yikun/Hydex
bash

该配置文件保存了项目 URL 与已经拉取的本地目录之间的映射。如果有多个子模块,该文件中就会有多条记录。 要重点注意的是,该文件也像 .gitignore 文件一样通过版本控制。它会和该项目的其他部分一同被拉取推送,这就是克隆该项目的人知道去哪获得子模块的原因。

查看子模块#

git submodule
993c7ff5953f4e525cc4b85a7ce7f4c8633eae2e Hydex (heads/master)
bash

更新子模块#

更新项目内子模块到最新版本

git submodule update
bash

更新子模块为远程项目的最新版本

git submodule update --remote
bash

Clone 包含子模块的项目#

对于你的主仓库项目合作者来说,如果只是 git clone 去下载主仓库的内容,那么你会发现子模块仓库的文件夹内是空的。

此时,你可以像上面「添加子模块」中说到的使用 git submodule update --init --recursive 来递归的初始化并下载子模块仓库的内容。

也可以分初始化和更新子模块两步走的方式来下载子模块仓库的内容:

git submodule init		# 初始化子模块
git submodule update	# 更新子模块
bash

但是,如果你是第一次使用 git clone 下载主仓库的所有项目内容的话,我建议你可以使用如下的代码格式来把主仓库和其中子模块的所有内容,都一步到位的下载下来:

git clone --recursive <project-url>
bash

删除子模块#

删除子模块比较麻烦,需要手动删除相关的文件,否则在添加子模块时有可能出现错误。

同样以删除 Hydex 子模块仓库文件夹为例:

  1. 删除子模块文件夹

    git rm --cached Hydex
    rm -rf Hydex
    bash
  2. 删除 .gitmodules 文件中相关子模块的信息,类似于:

    [submodule "Hydex"]
            path = Hydex
            url = https://github.com/Wu-yikun/Hydex
    bash
  3. 删除 .git/config 中相关子模块信息,类似于:

    [submodule "Hydex"]
            url = https://github.com/Wu-yikun/Hydex
            active = true
    bash
  4. 删除 .git 文件夹中的相关子模块文件

    rm -rf .git/modules/Hydex
    bash
Git Submodule 简明教程
https://coooredump.github.io/blog/productivity-tool/git-submodule/
Author Coredump
Published at June 10, 2026
Comment seems to stuck. Try to refresh?✨