Technical note
Git子模块常用操作
Git子模块本身的命令不多,真正容易漏掉的是主仓库只记录子模块的某个提交。子模块更新完成后,必须回到主仓库提交gitlink变化,否则其他人仍会取得旧版本。
参考
克隆包含子模块的项目
克隆时可以顺便初始化所有子模块:
git clone \
--recurse-submodules \
https://example.com/project.git
普通克隆完成后,也可以再初始化:
git submodule update --init --recursive
--recursive会继续处理子模块中的子模块。
添加子模块
添加时指定仓库地址、跟踪分支和本地目录:
git submodule add \
-b main \
https://example.com/common.git \
app
git submodule status
git status
git commit -m '添加common子模块'
Git会新增.gitmodules,并在主仓库中记录子模块当前提交。主仓库记录的是一个确定的提交,不是子模块目录中的全部文件。
已有子模块可以修改跟踪分支:
git submodule set-branch --branch main app
git add .gitmodules
git commit -m '调整子模块跟踪分支'
这个分支配置只影响git submodule update --remote。普通的git submodule update仍以主仓库记录的提交为准。
更新子模块
拉取主仓库后,将子模块切换到主仓库记录的版本:
git pull
git submodule update --init --recursive
如果需要取得子模块远程分支上的最新提交:
git submodule update --remote app
git status
git add app
git commit -m '更新common子模块'
最后两步不能省。子模块更新后,主仓库中的gitlink也发生了变化,需要提交才能让其他人取得同一个版本。
直接进入子模块开发时也一样:
git -C app switch main
git -C app pull
git add app
git commit -m '更新common子模块'
修改仓库地址
子模块迁移到新地址后,需要同时更新.gitmodules和本地配置:
git submodule set-url \
app \
https://example.com/common.git
git submodule sync --recursive
git add .gitmodules
git commit -m '修改子模块地址'
停用和删除
只想清掉本地工作目录,不修改主仓库历史:
git submodule deinit app
以后可以重新初始化:
git submodule update --init app
从主仓库中删除子模块:
git rm app
git commit -m '删除common子模块'
不要直接删除子模块目录。git rm会同时处理主仓库中的gitlink和.gitmodules配置。