git (git flow) 的通用工作流程使用功能分支,其中为每个新功能创建一个单独的分支。开发人员在这些独立的分支上实现新功能,然后将他们的更改合并回main
分支或master
分支。
该工作流的好处很明显:可以在 QA 环境中方便地部署和测试一个单独的分支,如果检测到严重错误,它根本不会合并到main
分支中。可以在同一分支中修复问题并改进代码。
同时,主分支仍然可以持续部署并免受这些问题的影响。
不幸的是,这种策略有一个明显的缺点——合并冲突。对于在某些时候不可避免的长寿命分支,这些冲突可能很难解决,因此更容易完全摆脱分支并从头开始。
同样,当它有很多冲突时,合并结果可能是不可预测的。
但是,这不是唯一可能的策略,本文将介绍一种替代方法来管理新产品功能,而没有上面列出的缺点。
根据 Git 的设计,当分支在同一个文件行中有不同的内容时,在合并过程中会发生合并冲突。
为了说明这一点,让我们考虑一个场景,其中两个团队正在实施对同一服务的更新。团队 A 正在整合信用卡支持,而团队 B 正在改进用户配置文件页面。这些功能似乎彼此无关。
然而,事实证明,与付款相关的代码之前与个人资料页面代码位于同一位置。因此,两个团队都将他们的代码提取到单独的分支中并重写了集成。
现在的问题是,谁将第一个将他们的更改合并到main
分支并假装问题不在他们这边,而另一个团队试图解决由此产生的冲突?
总之,避免合并冲突是不可能的,但我们当然可以使用以下众所周知的规则使它们更容易解决:
如果一个动作既困难又可怕,就多做几次
在 Git 术语中,这意味着我们需要尽可能频繁地合并(最好是在每次提交时)。当然,在那种情况下,冲突会更频繁地发生,但解决起来会容易得多。
它被称为基于主干的开发,意味着将更改直接推送到main
分支,并在不必要时避免使用分支。
在上面的示例中,如果两个团队定期将他们的更改推送到main
分支,他们会很快注意到他们正在尝试修改同一个文件。
更重要的是,他们本可以完全避免问题。考虑到这些更新,第二个团队将在第一个团队已经修改文件后开始进行更改。
细心的读者可能会想:一切听起来都很棒,但我们如何进行测试呢?每个功能的分支允许在发布之前单独测试整个新功能;如果我们不断地将更改集成到main
分支中,就没有机会了。
功能标志或功能切换是一个简单的动态标志,允许在运行时切换特定功能。通常,功能标志还允许为特定用户组启用或禁用功能,例如 QA 工程师、员工、特定客户等。
功能标志有几个额外的优点:
使用功能标志可以更安全地将更改推送到main
分支。当功能标志关闭时,更改不会影响任何人。
这种技术允许直接与main
分支一起工作或创建短期分支。因此,合并冲突变得非常罕见并且可以迅速解决。
总而言之,基于主干的开发与功能标志相结合是一种出色的技术,有助于避免因功能分支中的冲突更改而引发的许多问题。
然而,一如既往,没有一种放之四海而皆准的方法。它适用于在同一个存储库中工作的少数团队——增加这个数量通常需要一些调整。
此外,两种方法总是可以同时使用:根据具体情况和任务使用特性分支或特性标志。