Git 子模块

子模块

有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目。 也许是第三方库,或者你独立开发的,用于多个父项目的库。 现在问题来了:你想要把它们> 当做两个独立的项目,同时又想在一个项目中使用另一个。

我们举一个例子。 假设你正在开发一个网站然后创建了 Atom 订阅。 你决定使用一个库,而不是写自己的 Atom 生成代码。 你可能不得不通过 CPAN 安装或 Ruby > gem 来包含共享库中的代码,或者将源代码直接拷贝到自己的项目中。 如果将这个库包含进来,那么无论用何种方式都很难定制它,部署则更加困难,因为你必须确保每> 一个客户端都包含该库。 如果将代码复制到自己的项目中,那么你做的任何自定义修改都会使合并上游的改动变得困难。

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

开始使用

创建子模块

子模块创建指令参考如下:

1
2
3
4
5
git submodule add https://github.com/user/repo.git path/to/submodule


# 拉取指定分支的子模块
git submodule add -b branch_name https://github.com/user/repo.git path/to/submodule

子模块在创建后会生成一个 .gitmodules 文件,该文件包含子模块的配置信息。

1
2
3
4
[submodule "submodule-name"]
    path = path/to/submodule
    url = https://github.com/user/repo.git
    branch = master

如果有多个子模块,该文件中就会有多条记录。 要重点注意的是,该文件也像 .gitignore 文件一样受到版本控制。 它会和该项目的其他部分一同被拉取推送。

克隆含有子模块的项目

当你需要克隆一个包含子模块的项目时,推荐你使用如下命令 (它就会自动初始化并更新仓库中的每一个子模块, 包括可能存在的嵌套子模块):

1
git clone --recurse-submodules https://github.com/user/repo.git

当你在克隆这样的项目时,如果你忘记了使用 --recurse-submodules,那么默认只会包含该子模块目录,但其中还没有任何文件。

需要执行如下命令进行初始化并更新子模块:

1
2
3
4
# 初始化子模块
git submodule init
# 更新子模块
git submodule update

或者将两者命令合并:

1
git submodule update --init 

如果还要初始化、抓取并检出任何嵌套的子模块,建议使用如下指令:

1
git submodule update --init --recursive

更新子模块

默认情况下,git pull 命令会递归抓取子模块的更改。但是它 不会更新 子模块。它仅会显示子模块 “已修改”,且 “有新的提交”。

为了完成更新,推荐运行如下指令:

1
2
3
4
5
# 更新所有子模块
git submodule update --init --recursive

# 更新单个子模块
git submodule update --init

修改子模块 Remote 或 Branch

子模块的 .gitmodules 文件中记录了子模块的远程仓库和分支。

可以修改该文件,然后执行如下指令来更新子模块的远程仓库和分支:

1
git submodule sync

删除子模块

当你需要删除子模块时,可参考如下指令:

1
2
3
4
5
6
7
8
9
# 1. 取消初始化
git submodule deinit -f path/to/submodule

# 2. 删除文件+缓存
git rm -f path/to/submodule
rm -rf .git/modules/submodule-name

# 3. 提交
git commit -m "删除子模块"

参考网址

如果本文对您有所帮助,欢迎打赏支持作者!

Licensed under CC BY-NC-SA 4.0
最后更新于 2026-04-24 14:19
使用 Hugo 构建
主题 StackJimmy 设计