使用git subtree & submodule管理多个子项目

本文首发在segmentfault中

背景

最近工作中遇到了一个问题:随着项目越来越多,很多项目依赖同一个模板或是配置文件想同一管理,又不想分开维护,所以只能互相引用,或是各自维护,导致了后续的很多麻烦。

场景一: 很多公司手机端和pc同时开发,引用同一套模板,或者通用的组件库。

场景二:用gulp、webpack来打包,或是用node来开发会有一些通用的配置文件需要统一管理。

第一阶段:gulp等自动化工具手动同步


这个是我们最初使用的方法,比如有两个项目projectA和projectB,B项目依赖A项目中的一套模板。

问题1:开发中我们引用模块的时候,B项目要经过很长的路径引用才能引到A项目中的模板,这要求所有开发者本地文件路径保持高度一致。

问题2:使用webpack打包压缩静态文件的时候,A、B两个项目必须在同一个git分支,很容易搞乱。

问题3:修改完文件不能及时看到效果,还要手动同步一次。这点是开发中最致命的问题,做前端的都会有体会如果改了一个样式或是一个模板要通过一个很长的操作路径才能看到效果,是非常影响开发效率的。

结论:在用了几个月之后,各种问题暴露出来,我们必须找新的办法。

第二阶段:使用Git subtree

网上调研了很多方法,例如[git submodule](http://git-scm.com/book/en/v1/Git-Tools-Submodules),第二阶段最终选择了subtree,一是官网已经不再推荐使用submodule了,二是subtree实在是太方便易用了。(后来和同事商量了下发现submodule还是有使用价值的,在第三阶段中我们再分析。)

说到subtree易用,只需要2步就可以初始化好一个子项目:

第一步:添加远程仓库

语法:`git remote add -f <子仓库名> <子仓库地址>`

实例:`git remote add -f component [email protected]`

验证:`git remote -v` 可以看到已经你添加成功了一个新的远程仓库叫 `component `

第二步:创建本地目录

语法:`git subtree add --prefix=<子目录名> <子仓库名> <分支> --squash`

实例:`git subtree add --prefix=component component master --squash`

这时候会在本地新建一个叫 `component` 的文件夹,`--squash ` 会把subtree上的改动合并成一次commit

第三步:使用 ( pull & push )

pull:`git subtree pull --prefix=component component master --squash`

push:`git subtree push --prefix=component component master --squash`

注意:**必须在 `component` 的父级目录执行**,使用起来还不是很方便。

第四步:更方便的使用

可以在 `package.json` 里面加script语句来执行,这样在每个文件夹下都可以pull & push,强制统一,避免出错。

第三阶段:使用Git submodule

1. 添加:`git submodule add`

2. 添加后会在当前目录下生成一个 `.gitmodules ` 的新文件,里面会记录submodule的引用信息,在当前项目的位置以及仓库的url。

3.  `git submodule foreach git pull` 这样可以更新所有子模块。

这里只介绍了最基本的submodule用法,实际在多个项目中更新和修改submodule还是很多坑的,可以参考这篇文章  [Git Submodule的坑]([http://blog.devtang.com/2013/05/08/git-submodule-issues/])。** 所以我们规定在项目中只能pull子模块,修改的话只能到子模块中去push。** 这样避免了多人修改造成的冲突。

结论

1.在新员工加入团队时:一次性clone项目,submodule可以一起clone出来,只需添加--recursive递归参数就可以了,而subtree并不行,只能手动添加,不过可以借助神器Yeoman(一个自动生成项目脚手架的工具)来实现。

2.subtree适合像配置文件这种需要跟着项目走的情况。

3.submodule适合在开发阶段时引用,到了生产环境会被打包到指定文件内,而本身并不用跟着版本走的情况。

参考文章

1. 官网文档:Git Tools - Subtree Merging

2. 使用GIT SUBTREE集成项目到子目录

3. 用 Git Subtree 在多个 Git 项目间双向同步子项目,附简明使用手册

你可能感兴趣的:(使用git subtree & submodule管理多个子项目)