踏入新公司,发现了其管理项目的模式有两种形式:
- monorepo:单仓库,多个项目之间可以相互引用代码。
- git submodule:多仓库,一个项目引用其他项目的代码。
对于 monorepo 在前面学习有所了解,但是对于 git submodule 却是第一次接触,那么就来亲自体验一把。
git submodule
字面理解就是 git 的子模块。其作用就是,当你在一个项目中想使用另外一个项目的代码,且两个项目是独立的仓库,那么这时候你就该考虑使用它了。
首先,先创建两个项目,项目名分别为: gitsubmodule01
和 gitsubmodule02
,安装依赖,运行项目。
bash
# 项目1
pnpm create vite gitsubmodule01 --template react
# 项目2
pnpm create vite gitsubmodule02 --template react
然后在 gitee 上创建两个仓库,用于分别存放两个项目。
最后把刚刚创建两个项目推上去,分别采用一些列指令:
shell
git init
git add .
git commit -m "init"
git remote add origin https://gitee.com/xxxx/gitsubmodule_01.git
git push -u origin "master"
当进行完上面的步骤之后,就可以顺利进行接下来的工作了。
gitsubmodule02 编写共享组件
在 gitsubmodule02 里面编写一个组件,其内容和运行效果如下:
非常的简单。
gitsubmodule01 使用共享组件
gitsubmodule01 项目想使用 gitsubmodule02 项目中编写的共享组件,那么我们就需要把 gitsubmodule02 项目作为子模块嵌入到 gitsubmodule01 里面。
如何嵌入呢?
bash
# gitsubmodule01 项目中执行
git submodule add https://gitee.com/xxx/git-submodule02.git submodule02
就是把 gitsubmodule02 项目添加到 submoule02的目录下面,是这样的:
也会生成一个 .gitmodules
的文件,其内容为:
bash
[submodule "submodule02"]
path = submodule02 # 子模块路径
url = https://gitee.com/xxxx/git-submodule02.git # git 仓库地址
# 这里我还测试了一下,在深层目录中,执行该命令,生成的 path 属性也是深层次的
[submodule "src/layout/html_layout"]
path = src/layout/html_layout
url = https://gitee.com/xxxx/Three-Layout.git
这样就把 submodule02 项目中的代码嵌入到了 submodule01 项目中,然后被使用。
看,是不是非常的简单,so easy。。。只需要把项目嵌入,就可以使用其项目的代码。
体验完了,接下里就是了解一些 git submodule 的一些特性了。
理解单独的仓库
在前面过了,git submodule 是针对两个不同仓库的项目,也就是单独的仓库,在上面的初体验也是能够明显的感知的。那么针对 commit 、 分支等,是不是也是单独的呢?
单独的提交
当分别对项目代码中进行修改时,例如:
使用 git status 查看文件状态时,发检测出两个文件发生了变动:
那么这时候有意思的就来了:
- 当你站在 gitsubmodule01 目录上执行
git add .
命令时,只会提交当前项目的代码,而不会提交 submodule02 项目中的代码。 - 当在 gitsubmodule01/submodule02 目录上执行
git add .
命令时,才会提交 submodule02 项目中的代码。
小结:
这里也就充分说明了,两个仓库是独立的,相互不影响。提交代码时,也就需要进入对应的文件夹中执行命令(利用工具就另说了哈)。
切换文件夹路径,也就是找路径中的
.git
文件。
单独的分支
在上面已经验证了每个项目都是单独的仓库,那么针对分支操作也是一样的。
gitsubmodule02 项目中存在两个分支:master
和 dev
。
那么就需要进入 submodule02 目录中,执行 git switch dev
命令就进行分支切换。
发现两个项目在不同的分支上。
在这里就会存在一个问题,就是分支可能会产生混乱。这里是演示项目,只存在两个分支,还没有什么强关联,迭代什么的。但是当分支多了,就会形成一种组合关系,那么管理项目就会产生一定的困难。
这里就需要谨慎开发,注意。
克隆仓库
克隆仓库很简单,执行 git clone
命令即可。那么针对含有子模块来说,有什么不同吗?
bash
git clone https://gitee.com/xxx/gitsubmodule_01.git
克隆下来项目,安装依赖,运行项目。你就会发现报错,报的错误信息为:
找不到文件,那么当手动去找文件的时候,也会发现 submodule02 就是一个标蓝的空文件夹
submodule02 目录的文件不见了,那么这时候就需要执行命令来恢复:
bash
git submodule init # 初始化
git submodule update # 更新,拉取代码
# 或者
git submodule update --init
bash
# 如果子模块里面含有子模块,可以直接采用递归解决
git submodule update --init --recursive
.git 文件分析
先来看看 submodule02 目录里面的 .git
文件。
bash
gitdir: ../.git/modules/submodule02
会发生,是去找上一级目录下的 .git
文件(也就是 gitsubmodule01 项目的 .git
文件),该文件夹下存在 modules 文件,里面就是存放着项目的所有子模块内容。
里面就包含了两个子模块,一个 submodule02,一个深层次目录测试的项目。
如果子模块 gitsubmodule02 项目中继续存在子模块,在其内部也会存在 modules 文件夹。
总结:
- 子模块 .git 文件内容,具体在根项目中的 .git 文件中 modules 中保存
- 再次说明是单独的 git 仓库。
待续 git subtree
当一个项目想使用另外一个项目中的代码,并且每个项目独立仓库时,git submodule 是一个不错的选择。
git subtree 也是一个另外的选择,没有研究,后面待学。