为什么大多数 Git 工作流程对单独开发者无效
大多数 Git 教程和工作流程的问题在于,它们是由在拥有多个团队、代码审查流程和涉及至少三个不同环境的部署管道的公司工作的人编写的。当你是单独开发者时,你没有这些限制——但你也没有这些安全网。 GitFlow,这种在 2010 年代占主导地位的工作流程,就是一个完美的例子。它是由 Vincent Driessen 为一个特定问题设计的:管理需要同时支持多个版本的软件的发布。如果你正在构建一个客户本地安装的桌面应用程序,GitFlow 是有意义的。如果你是一个交付 SaaS 产品或客户网站的单独开发者,这完全是多余的。 典型的单独开发者与 Git 的旅程大体上是这样的:你刚开始时只提交到 `main` (或 `master`,取决于你什么时候学习 Git)。然后你阅读了一篇关于“专业 Git 工作流程”的文章,感到内疚。你实施了功能分支。接着你添加了一个 `develop` 分支,因为那是图示所示的。没过多久,你每天花 20 分钟仅用来管理分支,你甚至不确定它们中有一半为什么存在。 我也经历过。我曾有过名为 `feature/new-feature`、`feature/new-feature-2`、`feature/new-feature-actually-final` 和 `feature/new-feature-for-real-this-time` 的分支。如果你从来没有经历过分支命名危机,你要么是在撒谎,要么是你作为单独开发者的时间还不够长。 根本的问题在于团队工作流程是为了解决团队的问题而设计的:在多个成员之间协调工作,防止冲突,管理代码审查流程,并在共享环境中维持稳定。当你独自工作时,这些问题大多数根本不存在。如果没有其他人,你无法与其他人发生合并冲突。改变一切的三次提交规则
经过我的凌晨 2 点的灾难后,我开始分析我的实际工作模式。我调出了过去六个月的 Git 历史,查看了我创建的每一个分支、每一个合并和每一个解决的冲突。我的发现很有启发性。 90% 的功能分支在合并之前只包含三次或更少的提交。这些不是需要隔离的复杂、多周的功能。它们是小改进、bug 修复和增量更改,我人为地将它们分离到分支中,因为我认为这就是“真正的开发者”所做的。 剩下的 10%——实际复杂的功能——才是分支有意义的地方。但即使如此,我也注意到一个问题:导致问题的分支是我开放超过一周的那些。一个分支存活的时间越长,合并回去时发生问题的可能性就越大。 这让我提出了我所称之为的三次提交规则:如果一个更改需要超过三次提交,它可能太大,应拆分。如果无法拆分,那就是其中一种确实有帮助的分支及其稀有情况。 这个规则迫使我重新思考我的工作方式。我不再为“重设计整个 UI”创建一个分支,而是为“更新按钮样式”或“实现新的导航组件”创建一个分支。每个分支最多存活一两天,包含集中的更改,并干净地合并。 这种心理转换是显著的。我不再以“功能”的形式思考,而是开始以“可部署增量”的形式思考。每个分支都必须代表我可以交付去生产而不会破坏现有功能的内容。这自然使分支保持小且短期存在。我把一个 Bug 发布到生产环境的那一天(以及它如何改善了我的工作流程)
让我告诉你我职业生涯中最糟糕的部署。我正在做一个客户项目——一个小型酒店连锁的预订系统。我在一个功能分支上工作了两周(是的,我知道,我违反了自己的规则),添加了一个新的支付集成。 该分支与 `main` 大相径庭。我一直专注于支付功能,以至于没有及时处理直接对 `main` 的小修复和改进,以满足紧急的客户请求。当合并时间到来时,我在 14 个文件中遇到了冲突。 我解决了冲突,运行了测试(通过了),并部署到生产。一个小时内,我接到了客户的惊慌电话。预订表单坏了。不是新的支付集成——而是之前运行正常的基本预订表单。 发生了什么?在解决一个合并冲突时,我不小心保留了一个函数的错误版本。测试没有捕获到这一点,因为我没有为那个特定的边缘情况编写测试(吸取了教训)。这个 Bug 完全是我的错,但工作流程让这个错误变得简单。 那次事件让我明白了一件关键的事情:作为单独开发者,我最大的风险不是别人的代码,而是来自两周前我自己的代码。当我在项目的不同部分之间切换时,我实际上是在与过去的自己协作。而过去的我往往是不可靠的同事。 这个意识引导我进入工作流程的第二个支柱:一周规则。没有一个分支的存在时间超过一周。如果一个功能需要更长时间,我就将其拆分成可以在一周内完成和合并的小块。如果这不可能,我就使用功能标志将不完整的代码合并到 `main`,同时隐藏用户。 一周规则已经为我节省了无数次。它迫使我保持接近 `main`,这意味着我总是在使用当前版本的代码库。它防止了导致复杂合并冲突的那种差异。而且它让我对范围保持诚实——如果我不能在一周内完成某项任务,我可能尝试做得太多了。分支复杂性的真实成本
让我们来谈谈数字。我在简化工作流程前后追踪了三个月的 Git 相关活动。结果很明显:| 活动 | 前 (小时/周) | 后 (小时/周) | 节省的时间 |
|---|---|---|---|
| 创建和管理分支 | 2.5 | 0.5 | 2 小时 |
| 解决合并冲突 | 3.0 | 0.3 | 2.7 小时 |
| 决定使用哪个分支 | 1.5 | 0.1 | 1.4 小时 |
| 清理过时的分支 | 1.0 | 0.1 | 0.9 小时 |
| 变基和同步分支 | 2.0 | 0.2 | 1.8 小时 |
| Git 总开销 | 10.0 | 1.2 | 8.8 小时 |
为什么“尽早提交,频繁提交”对单独开发者是错误的
这里有一个有争议的观点:“尽早提交,频繁提交”的建议实际上对单独开发者是有害的。我知道这违背了传统智慧,但请听我说完。提交的目的不是创建一份每个按键的详细日志。而是创建有意义的检查点,讲述你的代码是如何演变的。当你独自工作时,你是唯一需要理解这一切的人。