背景
最近公司里多项目并行的时候, 发现在以前组管理的感觉比较混乱的分支方式(多个项目并行的时候, 同一个组件的代码需要维护多套分支)居然其实算是一个比较好的实现了...
这里的分支反而更加混乱. 索性梳理一下分支到底应该怎么管理, 才是最佳实现.
下面这部分是我目前的理解.
分支的场景
据我目前接触到和理解的, 会有以下几种常见的场景. 考虑到这里主要的障碍在于分支管理, 暂时假设一个组件的维护人员就是一人, 暂时跳过多人维护一个组件情况下的merge障碍问题(其实这块也比较要求模块设计的解耦, 多人改同一段代码这种情况本就不好合并, 我的理解是从设计上尽量避免对同一行冲突的修改). 根据[^6]中可知, 良好的模块化基本不会遇到代码分支带来的相同行修改的隔离问题.
- 一个分支对应一个项目, 包含多个组件的并行开发
- 多个分支对应多个并发项目面向不同业务场景, 同一套组件
- 一个项目对应多个组件分支, 各组件并行开发
- 多个组件对应多个主分支, 多个项目再各自开出对应的项目分支
- 上面几项中, 公共组件在多个项目中的使用
- 项目中只是用公共组件的发布版本
- 公共组件维护一个私源库, 每次迭代发布一个版本.
- 发布后的缺陷通过更新patch, 更新rpm包等形式, 如果各项目有涉及缺陷, 使用最新的组件包更新即可.
- 优点:
- 独立性强, 不需要因为业务项目拉出分支, 也进行项目拉出
- 缺点:
- 组件调试不便.
- git subtree
- 将一个目录自动提交到多个项目分支中的同一个组件目录下
- 个人只处理一个分支,但是实际上项目有多个分支.
- 这个感觉是一个比较好的处理手段.
- 独立分支维护
- 为了避免其他使用者对公共组件更新的感知不及时, 可以通过webhook等方式进行通知
- 项目中只是用公共组件的发布版本
- 依赖第三方组件如何管理问题
- 是单独维护一个分支用来记录使用的库及其版本的下载路径
- 还是直接把库提交到分支中.
版本发布模式
- 项目制发布模式: 项目制发布模式, 预先确定功能特性, 在所有功能开发完成后进行版本发布
- 发布火车模式: 大型套装分发类软件, 各部门之间互相依赖, 约定版本发布的时间
- 城际快线模式: 固定版本发布时间和质量维度, 时间较短
我理解, 项目制和发布火车模式有点相近. 都是约定一个集成时间, 开始各功能提交进行集成.
而城际快线就是高频集成的持续集成模式那种吧.敏捷开发?因为高频集成, 所以重构代码带来的代价也少, 这种比较贴合代码架构变更频繁的场景倒是.
分支管理的用途
- 一个长期稳定迭代的基线分支
- 这个分支只有当项目发布完毕时才合入代码.
- 项目进行中的不稳定的开发分支
- 这个分支在项目开启时,从基线拉出
- 项目发布后的缺陷修复所需提交的分支
- 定制项目的一些特殊需求无需合入基线.
潜在的问题
当一个项目开发中时, 开启了另一个项目, 需要用到目前正在第一个项目的分支中开发的功能
- 是否应该从项目分支再创建一个分支呢?
- 还是从基线拉出分支, 然后再从当前正在开发的分支合并功能代码过去呢?
- 根据现在的理解, 这个选择更合适, 分支统一从基线拉出, 这种分支流图更合理.
当一个功能即将开发完毕时, 但是由于对接方面的人时间计划来不及处理了,他的功能没有上车,这样的话, 对于我们的代码应该怎么处理呢?
- 我的理解是git的话可以在本地或是自己的一个branches里提交, 然后等到需要合并时, 再合入项目分支
- 或者可以通过stash暂存区来处理这个问题.
- 如果是svn, 是不是就只能注释这部分代码了呢?
- 似乎也可以像git一样, 创建一个自己的分支先提交, 但是这样的话, 如果每个人都有创建的分支的权限的话, 似乎就会比较混乱了把?
- 但是似乎这个也算是一个比较好的实现了.
- 毕竟不像git有约定的特性分支, 只能自己拉自己的特性分支了.
- 似乎也可以像git一样, 创建一个自己的分支先提交, 但是这样的话, 如果每个人都有创建的分支的权限的话, 似乎就会比较混乱了把?
公司研发了一套svn插件, 导致通过git-svn来完成本地使用git这个逻辑不太可行.
代码合并的最大成本主要是在于工具吗?
- 并不是, 是在于开发时, 是否考虑过和基线的兼容性问题, 基线理论上除了缺陷, 不应该有其他的操作合入
通用思考
从主分支里拉了一个新分支出来,在合并回主分支之前,必须持续地把主分支的更改尽早尽快合并到新分支。新分支永远保持 最新主干代码+新模块代码 的状态。
其实的确是对的, 如果基线修改了, 那么就应该尽快把基线的一些修改合并到你当前的分支中去, 避免将来无法合并
因为你merge代码的时候,用BC除非没有冲突的文件,只要有add和delete操作的文件你都要逐个逐行进行处理啊,更别提有冲突的文件了。用git做merge无冲突文件且版本号高于master分支就自动帮你解决了,你只需要解决冲突就行;
git合并分支容易的原因是,要经常和master分支merge,这样把冲突消灭在萌芽状态。
git可以合并commit到一个后来被修改过的文件>
Git可以修改和重构历史提交:使用Git本身的reset以及 rebase 命令可以修改或者重整/重构历史提交,非常灵活。使用强大的 stg 可以使得历史提交的重构更为简洁,如果您对 stg 或者 Hg/MQ 熟悉的话。
大厂文章
美团单周迭代
- 定期需求评审
- 多版本多需求并行开发(在需求分支内开发)
- 分支
- release分支
- 立项时从stage分支拉出
- 成果物从这个分支构建.
- 发版后合入到Stage分支.
- 其他开发中的分支也合入该分支的最新代码
- stage分支
- 承担稳定的代码功能的归档
- 通过jenkins job来完成分支的管理
- release分支
git代码分支模型
git flow
- 基线分支只合稳定以后的功能
- 各项目的dev分支, 存放满足需求的feature的开发, 稳定后打tag, 合回基线
- release分支, 从dev拉出, 包含所有功能, 处理发布所需, 完毕后打tag合回基线及dev分支
- hotfix分支, 修复后, 合入到上述所有分支
优劣势
- 流程清晰
- 管理严格
- 长期分支的同步开销较大, 不适合快速发布
github flow
- 只有master分支, 只有部分管理员有提交权限, 其他人通过在自己分支完成功能后提交PR, 通过评审和自动化测试进行兜底
- 各feature及缺陷修复分支
优劣势
- 分支简单, 适合快速迭代
- 不适合多环境多版本项目并行产品
gitlab flow
- 似乎和git flow有点类似, 多出了production, release等分支?
TBD flow(Trunk Based Develop)
- 开发及缺陷修复基于trunk, 只有快速发布, 完全没有分支管理
TBD++ flow
- 基于功能的主分支
- trunk和feature分支需同步更新
- trunk分支有自动化测试自动执行
- 基于发布的release分支
- release分支发布后打Tag, 但依旧长期运行, 如果发现缺陷, 往这个分支及master分支合入缺陷修复, 这个发布分支打新的tag
todo: patch管理定制/上游代码, 是否可行?
巧用svn create patch(打补丁)方案解决定制版需求_golden_lion的博客-CSDN博客