Git项目官方分支工作流规则理解及合并逻辑疑问咨询
对你现有理解的修正与确认
你对分支流转大方向、工作流设计逻辑的判断基本准确,仅对seen分支的定位存在小偏差:
maint:定位无误,跟踪当前仍在维护的上一个稳定版本,仅接收关键bug、安全问题的热修复,是稳定性最高的分支。master:定位无误,是下一个正式稳定版的基线分支,所有进入master的提交都已经过完整回归测试,随时可以切出新版本。next:定位无误,作为实验性集成分支,会合并所有经过初步审阅、计划进入后续版本的主题分支,专门用于开展跨特性的回归测试,上面的提交如果测试不通过可能被直接剔除,不会进入master。seen(早期版本叫pu/proposed updates):你的理解有误,这个分支是维护者的“初步测试收容区”,所有邮件列表收到的补丁只要没有明显的低级错误,哪怕还没完成正式审阅,都会先合并到seen做最基础的集成验证,上面的内容随时可能被重置、删除,是四个分支里稳定性最差的,你提到的“已完成审阅”实际是补丁进入next的准入门槛。
你对主题分支使用规则、尽量避免向下合并、临时测试分支可丢弃的设计逻辑的理解完全准确,核心目标就是在保证稳定分支历史整洁、提交可追溯的前提下,尽可能降低多特性并行测试的成本。
关于“向上/向下”流转的方向,你的理解完全正确:四个分支稳定性从高到低排序为maint > master > next > seen,文档里说的“向上”集成,就是从稳定性更高的下层分支,往稳定性更低、内容更新的上层分支合并,也就是maint→master→next→seen,所有常规集成都必须沿这个方向执行,绝对禁止反向把上层分支合并到下层,避免把未经过充分测试的代码带入稳定分支。只有当bug修复被直接提交到上层分支、确认下层稳定分支也存在相同问题时,才允许用git cherry-pick把单个修复提交“向下”拣选到下层分支,这也和你看到的文档描述完全对应。
关于maint分支快进的核心疑问解答
你疑惑的“为什么maint可以快进到master、不会出现分叉”,核心原因是git工作流有一条强制执行的规则:
任何提交到
maint的热修复,必须第一时间沿向上路径合并到master、next、seen,保证所有上层分支永远包含下层分支的全部提交。
也就是说,从规则层面就不允许maint存在任何master没有的提交,根本不会给两个分支留出分叉的可能:
- 假设当前
maint跟踪v2.42.x版本,master在开发v2.43版本:- 当你给
maint提交了一个v2.42.1的热修复提交,提交完成后必须立刻执行合并操作把maint合入master,不管合并时是快进还是生成临时合并提交,最终master的HEAD一定会把这个热修复纳入自己的提交历史,且maint的最新HEAD必然是master最新HEAD的祖先节点。 - 整个v2.43的开发周期里,每一次往
maint新增热修复,都会立刻同步合并到master,所以master的提交历史永远是maint提交历史的严格超集。
- 当你给
- 当v2.43.0正式从
master发布时,maint的HEAD一定是v2.43.0这个提交节点的祖先,这时候切到maint执行你提到的命令:
本质就是把git checkout maint git merge --ff-only mastermaint的指针直接移动到v2.43.0的位置,完全满足快进条件,不会报错,也不会生成额外的合并提交。 - 快进完成后,
maint就开始跟踪新发布的v2.43.x版本的热修复,进入下一个周期循环。
你担心的“maint有热修复导致提交分叉”的情况,本质是默认热修复会停留在maint不同步到master,但这在git.git的官方工作流里是严格禁止的操作——如果有人往maint提交了修复却没有同步合并到上层分支,维护者会第一时间要求补上合并操作,从流程上杜绝了分叉的可能。
另外补充一点:只有master和maint两个稳定分支要求保持提交历史的线性可追溯,next和seen作为临时集成分支,本身就会存在大量合并提交,甚至会被定期重置重写,不需要保持线性历史,这也是为什么工作流只强调两个稳定分支的快进要求,对上层测试分支的历史整洁度没有强制约束。
内容的提问来源于stack exchange,提问作者ElderFuthark

