跳到主要内容

Git 子模块

子模块(Submodule)允许你将一个Git仓库作为另一个Git仓库的子目录。它常用于:

  • 引用外部依赖库
  • 复用公共代码
  • 模块化大型项目

添加子模块

git submodule add https://github.com/example/lib.git libs/lib

这会在项目中创建一个 libs/lib 目录,并添加 .gitmodules 配置文件:

[submodule "libs/lib"]
path = libs/lib
url = https://github.com/example/lib.git

克隆包含子模块的仓库

方法1:递归克隆

git clone --recurse-submodules https://github.com/example/project.git

方法2:先克隆后初始化

git clone https://github.com/example/project.git
cd project
git submodule init
git submodule update
# 或者
git submodule update --init

方法3:同时初始化子模块的子模块

git submodule update --init --recursive

更新子模块

更新单个子模块

cd libs/lib
git fetch origin
git checkout main
git pull origin main

更新所有子模块

git submodule update --remote

在拉取时自动更新子模块

git pull --recurse-submodules

删除子模块

删除子模块步骤较多,需要手动清理:

# 1. 删除 .gitmodules 中的条目
git config -f .gitmodules --remove-section submodule.libs/lib
git add .gitmodules

# 2. 删除 .git/config 中的条目
git config --remove-section submodule.libs/lib

# 3. 删除子模块目录
rm -rf libs/lib
git rm libs/lib

# 4. 删除 .git/modules 中的子模块数据
rm -rf .git/modules/libs/lib
git add .gitmodules

# 5. 提交更改
git commit -m "删除子模块 libs/lib"

子模块命令汇总

命令说明
git submodule add url path添加子模块
git submodule init初始化子模块配置
git submodule update更新子模块
git submodule status查看子模块状态
git submodule foreach 'command'在每个子模块执行命令
git submodule deinit path清理子模块配置

查看子模块状态

git submodule status

输出示例:

a1b2c3d libs/lib (v1.0.0)
b2c3d4e libs/utils (main)

状态符号:

  • +:子模块版本与索引不一致
  • -:子模块未初始化
  • U:子模块有冲突

在子模块中工作

cd libs/lib

# 创建工作分支
git checkout -b fix-bug

# 修改后提交
git commit -m "修复bug"

# 推送到子模块仓库
git push origin fix-bug

# 返回主仓库
cd ../..

注意事项

  1. 子模块是静态的:子模块提交锁定,不会自动更新
  2. 路径唯一性:每个子模块路径必须唯一
  3. 权限问题:推送子模块需要相应权限
  4. 删除需谨慎:务必完全按步骤删除,否则可能残留文件

使用场景

  • 依赖管理:管理第三方库版本
  • 代码复用:多个项目共享公共代码
  • 大型项目:拆分为多个仓库便于管理