在开发一个大型项目时,经常会遇到多个团队共用某些公共组件的情况。比如前端团队维护一套 UI 组件库,后端团队也在管理自己的工具包。如果把这些代码直接复制到各个项目里,更新起来特别麻烦。这时候,Git 子模块(Submodule)就能派上用场了。
什么是 Git 子模块
简单来说,Git 子模块就是把一个 Git 仓库作为另一个仓库的子目录来引用。它保留了原仓库的独立性,同时又能被主项目跟踪。就像你在家里放了一本别人写的书,书的内容不属于你,但你知道它放在哪个书架上。
添加一个子模块
假设你正在做一个网站项目,需要用到一个叫 common-utils 的公共库,它的地址是 https://github.com/team/common-utils.git。你可以这样把它加进来:
git submodule add https://github.com/team/common-utils.git lib/utils
执行完这条命令后,你会看到项目里多了个 lib/utils 目录,里面就是那个公共库的内容。同时根目录下会生成一个 .gitmodules 文件,记录了子模块的信息。
克隆带子模块的项目
当你把项目分享给别人,或者换一台新电脑重新拉代码时,直接 git clone 是不够的。子模块目录会是空的。
正确的做法是:
git clone https://github.com/you/your-project.git
cd your-project
git submodule init
git submodule update
也可以一步到位:
git clone --recurse-submodules https://github.com/you/your-project.git
更新子模块内容
子模块本身是一个独立的仓库。如果你想更新它到最新版本,需要进入对应目录操作。
cd lib/utils
git pull origin main
然后回到主项目提交一下变更,这样其他人就知道你用了新版本。
切换子模块的分支
有时候你希望子模块跟踪某个特定分支,而不是固定在一个提交上。可以在 .gitmodules 里设置:
[submodule "lib/utils"]
path = lib/utils
url = https://github.com/team/common-utils.git
branch = dev
之后用 git submodule update --remote 就能拉取该分支的最新提交。
删除子模块
如果某个子模块不再需要,删除稍微麻烦点,不能直接 rm -rf。
先从 Git 中移除:
git submodule deinit lib/utils
rm -rf .git/modules/lib/utils
git rm -f lib/utils
最后别忘了删掉工作区的文件夹:
rm -rf lib/utils
实际场景中的注意事项
有个朋友之前做小程序项目,把登录逻辑封装成一个子模块给三个产品线共用。后来其中一个团队私自改了子模块但没推送到主仓库,结果其他两个项目更新时出问题。所以要记住:子模块的修改一定要提交并推送,否则别人拉不到你的更改。
另外,CI/CD 流水线中也要注意开启子模块拉取选项,不然构建可能失败。