likes
comments
collection
share

子项目管理【Git Subtree】

作者站长头像
站长
· 阅读数 9

背景

假设有两个项目A、B,分别有代码仓库a、b,而AB存在很多可以共用业务组件、方法或者是模块,如果想要将公共的模块抽离出来管理,实现复用,有什么好的方式呢?

  • npm:node package manager,不仅仅是node的包管理工具
  • composer:类似php版的npm、php版本的maven
  • git submodule:这是git之前推荐的管理子项目的方式
  • git subtree:git现在更推荐这种方式

npm、composer:比较麻烦,更适合代码稳定的场景,我们将公共部分拆分出来,当公共部分快速迭代的时候,每次更新npm代码,还需要手动更新其他项目的依赖版本;同时,因为相互之间是隔离的,无法保证一次版本升级就实现需求。git submodule、git subtree:适合业务迭代很快,公共仓库的变化频率高,并能双向同步,可以直接在a/b仓库修改公共部分;缺点是没有依赖管理功能,并且依赖项目必须有公共部分仓库的开发权限。

Git Subtree是什么?

它提供了一种可以将一个代码仓库作为另一个仓库的子目录,并能保证两个仓库独立性。

它是git官方提供的能力,虽然不具备版本管理的能力,但是一些需要快速迭代的场景下,能满足我们的需求。用一句话来描述它的好处:

经由 Git Subtree 来维护的子项目代码,对于父项目来说是透明的,所有的开发人员看到的就是一个普通的目录,原来怎么做现在依旧那么做,只需要维护这个 Subtree 的人在合适的时候去做同步代码的操作。

它的原理和使用方式

我们首先要有两个项目,vue-main、vue-app,然后它们两个共用的的公共项目common-obj。我们通过使用subtree的方式来阐述其原理

1. 初始化子项目

cd vue-main
git add subtree --prefix=[存放subtree的相对地址] [common-obj的git地址] [分支]

vue-app也同样执行执行完这个命令,会自动产生一个commit,就会把common-obj拷贝一份到[存放subtree的相对地址]目录下。

2. 正常的修改代码、提交代码

这个过程中我们难免会变更到common-obj里面的代码,但是我们不需要关注其他任何事,只需要正常的变动代码、提交代码即可。举个🌰:

  1. 在vue-main中,修改了vue-main自己src下的某个文件
  2. 修改了[存放subtree的相对地址]下common-obj的某个文件
  3. 正常的提交流程

完成上述提交,我们只是把vue-main自己的变更,而common-obj的变更则会被放到.git文件下的subtree-cache中子项目管理【Git Subtree】所以关于common-obj的提交,并没有同步到远程仓库中去,此时其他依赖common-obj的项目也并不能感知到在vue-main中的修改。

3. 将common-obj的变更同步到它的仓库

我们需要在进行过变更(vue-main)的项目文件路径下执行:

git subtree push --prefix=[存放subtree的相对地址] [common-obj的git地址] [分支]

这样会遍历当前在vue-main中对common-obj的变更,将其提交到远程仓库。

4. 其他项目获取最新的subtree

vue-app想获取最新的subtree,只需要执行

git subtree pull --prefix=[存放subtree的相对地址] [common-obj的git地址] [分支] 

这样就可以将vue-app下的subtree更新为最新的变更了。

比较适合的场景

多个项目共同依赖一个库,这个库会快速迭代更新的场景可以考虑使用subtree。如果其他某些项目想要一个稳定的版本,也只需要在subtree中拉出一个v1.0.0分支,pull的时候分支固定为v1.0.0即可。另外,如果我们项目发布上线,打包的代码必须执行过git subtree pull命令,保证发布的代码中包含了subtree的代码,避免代码出现问题。对于微信小程序的开发,如果需要公用某个仓库, 使用git subtree是一个不错的选择,因为微信小程序上传的是本地打包后的结果。总之,GItsubtree是一个很有用的git操作,可以简化多个仓库的管理,并能提高代码的可用性。