我从事专业代码编写工作已有五年多了。前四年,我从未关心过我的拉取请求 (PR) 的大小。然而,去年,我从提交包含数千行更改的大型 PR 转变为将它们分解为更小、更易于管理的 PR。这种转变的好处是巨大的,在这篇博客中,我将分享这些优势。
根据GitHub 的说法,拉取请求是:
拉取请求是将一组更改从一个分支合并到另一个分支的提议。在拉取请求中,协作者可以在将更改集成到主代码库之前审查和讨论提议的更改集。
从本质上讲,pull request 是一种协作方式;我们应该尽一切可能来加强这种协作。改善这种协作的一个有效方法是保持 PR 规模较小。
没有通用的定义来区分小型 PR 和大型 PR。仅依靠更改的行数是不够的,因为自动生成的代码和测试可能会夸大行数。当我在本文中提到小型 PR 时,我的意思是将大型 PR 分成多个较小的、逻辑上连贯的 PR。每个较小的 PR 都应该是独立的、可合并的和可部署的。
我不主张人为的分裂,比如将 PR 分成两个,一个包含所有代码,另一个只包含测试,因为这种方法无法产生我在下面分享的任何好处。
如果让程序员检查 10 行代码,他会发现 10 个问题。如果让他检查 500 行代码,他会说看起来不错。
这句话虽然幽默,但却很有道理。每个人都忙于自己的工作,当你要求某人审阅 PR 时,你实际上是在占用他们的时间。审阅 PR 需要审阅者从自己的工作中切换上下文,如果审阅需要相当长的时间,他们可能很难回到自己的工作中,这可能会影响他们审阅的积极性和承诺。
较小的 PR 只需要大约 20-30 分钟即可完成审核,与可能需要 2-3 小时的 PR 相比,处理起来要容易得多。此外,较大的 PR 往往会导致疏忽,因为我们的注意力有限,而且在单个 PR 中切换大量更改可能会让人感到困惑。根据我的经验,较小的 PR 往往会获得更好的反馈,并带来更有意义的设计对话。
此时,我正在考虑将我的 PR 添加到我的遗嘱中,以防我死后它仍在审核中。
较长的 PR 需要审阅者投入大量时间,因此不太可能引起注意 — 尤其是当它们与高影响力功能无关时。另一方面,较小的 PR 会很快得到审阅,因为它们需要审阅者投入的时间较少,而且干扰较少。
这种审查速度对于满足项目期限至关重要;我见过项目被延迟,因为高级审查员无法为大量 PR 分配时间(尽管这种情况可能发生在小型 PR 中,但大型 PR 的风险本质上更高)。
在设计变更后重新进行大型 PR 就像在刚建好的船上重新摆放甲板椅……然后将其沉没。
我们都经历过这样的情况:有人在 PR 审查期间意识到,另一种设计会更易于维护且更具前瞻性,而我们需要花费更多时间根据新设计重新制定 PR(并不是说他们完全同意最初实施的设计 :p)。这很自然,因为有时一旦你看到它们以代码形式编写出来,事情就会变得更加清晰,你会开始注意到在设计阶段可能错过的方面。
对于大型 PR,这可能是一个重大问题,因为您必须重新设计许多元素,但对于较小的 PR,更改更容易。更重要的是,返工的可能性较低,因为审阅者更有可能尽早发现问题并在初始 PR 中解决这些问题,从而使后续 PR 能够基于新设计。
较小的 PR 也有利于您作为 PR 的作者。它们有助于逐步测试较小的更改,而不是一次性测试整个项目。测试较小的更改会导致对系统的每个组件进行更详尽的测试,从而减少生产错误。这适用于您或专门的 QA 工程师执行的自动测试和手动测试。
此外,较小的 PR 可以降低错过测试用例的可能性,因为您可以专注于有限的范围而不是整个系统。
写测试?这听起来像是未来的我的问题。
我见过开发人员(包括我自己)犹豫是否要编写自动化测试,因为他们认为这需要投入大量时间,而无法为功能/产品带来立竿见影的“可见”价值。较小的 PR 可以通过限制所需测试的数量和编写测试所花费的时间来减少这种阻力。
无论测试多么彻底,生产错误都会发生!能够调试生产中的错误至关重要,因为生产错误会直接影响用户、业务或两者。对于大型 PR,更改的表面积也很大,这使得查找问题的根本原因既耗时又困难。另一方面,较小的 PR 包含的代码较少,因此调试速度要快得多。
调试小的变化就像发现打字错误;调试大的变化就像校对百科全书。
最后但同样重要的是,较小的 PR 也对您的产品经理和用户有帮助。通过使用小型 PR,您可以不断将系统的各个部分推向生产,这有助于获得用户的早期反馈,并在需要时进行早期课程修正。
跳过早期反馈就像烹饪一顿五道菜的饭却什么都没尝到——你只是希望它不会是一场灾难。
小型 PR 的好处很多,上面列出的几点是我个人体验过的最有影响力的。如果您遇到了小型 PR 的其他优势或大型 PR 的挑战而我还没有提到,请发表评论,分享您的见解。
我希望这篇文章能激励您接受较小的 PR。如果您已经加入,我希望它能强化这种做法的价值。
感谢您的阅读,下次再见,继续编码并保持好奇心!