如何创建有效的 Pull 请求 确保你的 PR 有测试支持 写一个有意义的 PR 标题 写一个有意义的描述 尽可能避免过大或过小的 PR 在你的 PR 中应用单一职责原则 避免无效的更改 避免格式更改 确保你的代码有注释,尤其是那些比较难的部分 提前提供上下文并提供自己的 PR 审查意见 利用外部工具集成 将 Pull 请求视为有价值的文档

2025-05-27

如何创建有效的 Pull 请求

确保你的 PR 得到测试支持

撰写有意义的 PR 标题

写一个有意义的描述

尽可能避免过大或过小的 PR

将单一职责原则应用于你的 PR

避免无效更改

避免格式更改

确保你的代码有注释。尤其是那些比较难的部分。

提前提供背景信息并提供自己的 PR 审核意见

利用外部工具集成

将 Pull 请求视为有价值的文档

拉取请求(Pull Request),本文下文简称为 PR。这个看似不起眼却必不可少的步骤,位于你精彩闪亮的新提交和主分支之间。PR 之所以不起眼,是因为我们知道自己的代码整洁有序,不希望那些恶意的代码审阅者对我们心爱的代码库提出那些无用且令人讨厌的评论,不是吗?

当然,我们确实需要。总的来说,代码审查并非坏事 :) 代码审查是一种在团队中传播知识的方式,也能让你的代码获得更多的关注。有些人可能会认为结对编程是代码审查的替代方案。没错,只要你能够接受团队中只有一个人了解你的代码就行。然而,你可能和某个人结对几个小时,然后那个人仍然可能想出与你最初的想法完全不同的东西。所以,代码审查是一个确保每个人都达成共识的机会,同时也能为你的工作获得高质量的反馈。

拉取请求的质量常常被忽视。糟糕的拉取请求不仅会在代码审查时造成摩擦(争论、争吵、浪费时间,最终导致项目失败),还会降低生产力,增加在生产环境中引入问题的几率。干净整洁的拉取请求有助于加快流程、缩短代码审查周期,并提高产品的整体质量。

因此,这里有一些关于如何编写有效的 Pull 请求的提示(请注意,这里的示例完全是虚构的)。

确保你的 PR 得到测试支持

这对我来说很重要,可能是最重要的。如果你必须选一条建议,那就选这条吧。

我们都是大忙人,对吧?我们有很多事要做。那么,你有没有收到过修改代码(不是那种简单的拼写错误修复之类的)且没有测试的拉取请求?我遇到过,而且很多次。而这些天来,我对这些请求的反应几乎都一样:“拜托,你能不能添加一些测试来证明你所做的修改确实经过了验证?”

我为什么要这么苛刻?其实是因为没有测试,我被迫付出巨大的努力,不仅要理解逻辑,还要找出任何可能真正破坏代码的小问题和依赖关系。如果你是某个领域的专家,这种情况尤其可能发生。在这种情况下,你很有可能总是会收到这种类型的 PR,提交者实际上只是想让你在编写任何测试之前验证一下整体方法和源代码。不用说,这很糟糕。非常糟糕。别误会我的意思,寻求帮助本身并没有错,但有更好的方法,比如要求进行结对编程或进行非正式的结对代码审查。这样,审查者的时间就能比突然提出的完全异步的 PR 得到更有效的利用。

通过在 PR 中编写测试,你可以向审阅者提供实际证据,证明你已经亲自测试过代码。你编写的测试应该超越通常的乐观测试场景。同样,通过提供负面测试,你可以证明你已经做好了准备工作,并且已经思考过出错时可能出现的情况。测试还能帮助你完善逻辑,并发现可能被忽视的隐藏问题。

最重要的是,测试不仅能提供证据,还能为你的审阅者提供很好的文档,让他们了解你想要证明什么,以及你为什么认为你确实证明了这一点。“为什么和“如何”这两点都提供了基本信息,可以帮助判断 PR 是否有效,或者它是否不完整、缺失部分内容或完全没有抓住要点。

撰写有意义的 PR 标题

这听起来有点琐碎,但实际上却很常见,而且经常被忽视。尤其是在单人项目上,时间紧迫,不会太关注细节的时候。但话说回来,如果你考虑到未来,很有可能以后还会有人加入,而如果你不注重头衔,最终就会出现这样的情况:

你能说出这个 PR 上发生了什么吗?

你能看出我当时在做什么吗?嗯,你看得出来我在重构一些代码,修复一些错误,但你完全不知道具体做了哪些改动。这当然是一个虚构的例子。但通常情况下,这样的事情意味着你必须逐一点击每个 PR 才能弄清楚到底发生了什么。想象一下,你是这个项目的新手,那该有多累啊。

标题需要简短、简洁,但同时需要传达变更的总体目的。如果您无法用一个标题概括您的 PR,那么很可能您的变更涉及的内容太多,这时您应该重新考虑是否应该将您的工作拆分成多个 PR。

写一个有意义的描述

PR 的描述应该有意义。请记住,审阅者在看到 PR 标题之后,接下来看到的是描述。好的 PR 描述应该告诉我们:

. 您想做什么。.
您是如何做的
。. 您为什么决定这样做。.
您如何支持此 PR。

例如,比较一下这些:

没有描述的 PR
PR 描述扩展标题
公关显然没有解释任何事情

下面这个:

良好的 PR 描述

因此,虽然第一个例子中没有任何描述,或者 PR 标题中有一些被删减的描述,或者指向未来某个演示的完全无用的描述,但这个例子中,工程师提供了一些关于问题的良好背景信息,解释了为什么需要这个 PR 以及为什么这样做。最后,它还提供了一些关于 PR 安全性以及已尝试的测试的信息。可能并不完美,但肯定比其他例子更有用,解释性也更强。

尽可能避免过大或过小的 PR

谁不害怕那神话般的超过 100 个文件的 PR?我做过一些,但我并不以此为荣。巨大的 PR 通常是长期分支、大规模重构、大量新功能的成果,或者仅仅是来自那些极具创造力的贡献者,他们能够快速创建复杂的代码并进行测试。然而,这些都不是大规模 PR 的真正理由。即使我们足够幸运,拥有技术精湛的工程师,他们的代码编写速度能像孩子吞下糖果盒一样快,但这并不意味着我们的审阅者也能拥有同样的能力来处理包含数百个修改的 PR。

另一方面,如果每次代码变更都单独提交一个 PR,会给代码和 PR 审核流程带来很大负担,并且可能会造成开发中断,影响开发进度。与大型 PR 不同,有时我们别无选择,只能提交小型 PR,因为我们可能只需要修改一个文件,而且修改量很少。这完全没问题。例如,我们不应该为某个功能创建五个不同的 PR,每个 PR 包含一个文件,而这些功能本身就足够紧密且逻辑相关,因此可以放在同一个 PR 中。

我不会设定一个理想的 PR 大小,因为我认为没有一个是固定的。但我相信,一旦文件数量超过 20 个,审阅者就很难在脑海中勾勒出所有变更以及这些变更带来的后果。进行测试可以缓解这个问题,但在提交一个开始感觉很大的 PR 之前,我们应该问问自己,是否愿意审阅这么多文件。如果我们觉得我们自己难以承受,那么我们应该体谅审阅者,将 PR 拆分成更小的相关部分。

将单一职责原则应用于你的 PR

单一职责原则在某种意义上也适用于 PR。正如您希望模块、类或函数拥有并封装单一职责一样,您也希望您的 PR 封装并拥有一组逻辑上相互关联且封装好的变更。换句话说,您不希望一个 PR 包含多个逻辑上不相关的变更。

将不相关的更改合并到同一个 PR 中的一个典型问题是,如果代码审查时间超出预期,那么该 PR 中包含的所有功能都将被阻止。想象一下,一个紧急的错误修复与一个不相关的 PR 一起提交,而这个 PR 包含多个需要审查的部分。重要的错误修复将被阻止,直到 PR 被修复。而如果您提交两个单独的 PR,那么快速简单的错误修复可以继续提交到主分支,而较长且冲突较大的 PR 则得到审查。

通常,当您始终在 fork 上的 master 分支上工作时,可能会不由自主地多次发生此问题。如果您要交付连续的更改,这完全没问题。但是,一旦您预见到多个并行更改,就应该考虑切换到 fork 上的临时本地分支,这样您就可以提交多个独立的 PR。

避免无效更改

诸如添加或删除新行、空格、制表符等更改根本不会更改文件,而只会给您的 PR 增加噪音并使其看起来比实际更长。您应该避免这种情况,因为此类更改会使您的 PR 看起来更混乱、更粗心。而您并不是粗心大意,对吗?说实话,当我看到这些模式的评论时,我的内心会立即对整个 PR 产生警惕。我不知道为什么。这可能是一种心理模式,就像那些解释盘子里看起来整洁的食物味道更好的模式一样。以类似的方式,由于清洁度而看起来很差的 PR 整体上看起来更糟并会引起警报。

此 PR 部分没有变化

避免格式更改

与上述观点类似,至少从心理层面来说,你应该避免在 PR 中更改代码格式。如果你需要更改格式,请专门为此目的提交一个 PR,并与你的同事讨论。诸如将制表符替换为空格、将空格替换为制表符、更改括号位置、将一行拆分为两行或将两行合并为一行之类的格式更改,都会导致将审阅者的注意力转移到与 PR 本身无关的主题上。

猜猜这个 PR 有什么变化

猜猜上面发生了什么变化?没错,你猜对了。什么都没变,或者几乎没有变化,或者肯定没有任何相关变化。

请记住,审阅者很可能已经在努力跟进你的 PR,并试图理解你的意图。你最不想做的就是引入不相关的样式更改,以免造成混乱。

确保你的代码有注释。尤其是那些比较难的部分。

沟通对于软件工程师来说至关重要。我再怎么强调也不为过。虽然我完全赞同代码整洁、自文档化的原则,但很多时候,仅仅命名和结构是不够的,工程师需要提供几行代码来解释代码想要做什么,或者为什么这样做。

再次强调,你需要设身处地为代码审查者着想,思考:“如果有人给我同样的代码让我审查,我会哭吗?”、“如果我完全不了解代码执行的上下文,我能理解吗?”。我们或许不必走极端,比如说“连小孩子都能理解”,但希望你能理解我的意思。

我们越能轻松有效地沟通我们正在做的事情,PR 就能越快被审核,错误也能越快被发现。所以,花些时间尝试以有效的方式沟通,无论如何都会带来巨大的回报。不用说,完成这一步后,代码就完成了文档化,这对新员工来说是一个很大的福利。每个人都喜欢优雅且文档齐全的代码。

提前提供背景信息并提供自己的 PR 审核意见

大多数源代码管理系统(例如 Github)都允许您审查自己的 PR。您可以利用这一点提前提供反馈。这些信息可能超出 PR 描述本身,可能与任务本身相关,也可能特定于某些文件,或者只是一般背景信息、外部评论、历史记录等。

例如,“这是我们前几天在 Sprint 开始时讨论过的异步任务执行器方法”或“ Joe 建议的指标聚合器线程已在此文件中实现”之类的注释,不应该出现在代码本身中,而且可能与上下文关联性太强,不适合放在描述中。然而,将这些注释添加为注释可以为评审提供重要且有用的上下文,我们可以将它们作为我们自己的代码评审,附加到 PR 本身的顶部或单个文件上。

利用外部工具集成

有些工具可以理解拉取请求并将其与现有的跟踪系统关联起来。例如,在 JIRA 中,如果您在 PR 标题中包含工单 ID,JIRA 会自动将所有 PR 信息包含在工单中。这对于跟踪不同的任务并将其与实际的工程工作进行映射非常方便。

JIRA Git 集成

大多数项目管理工具都与 Git 有某种集成,所以请继续利用它!

额外福利:如果你将源代码管理工具(例如 Github)与协作工具(例如 Slack、Webex Teams、Microsoft Teams 等)集成,并且你的 PR 井然有序,那么你将拥有一个绝佳的团队空间,其中包含所有代码变更,可供你的团队随时审阅、随时了解,或者几个月后再回来查看过去的变更。只要你的 PR 得到妥善处理,所有这些都是免费的。

将 Pull 请求视为有价值的文档

如果以负责任的方式创建 PR,它可以成为非常重要的文档来源。它对您要做的事情提供了有意义的描述。它包含一系列旨在实现您的任务的更改,并包含一组测试来验证需求是否确实得到满足。

如果操作正确,现有工程师或新员工可以轻松浏览已关闭的 PR 列表,以获得良好的历史分段视图,了解过去几个月或几年内团队或个人逐步引入项目的最显着的变化。

然而,为了有价值,Pull Request 确实需要像我们的代码一样好、整洁。

希望以上建议能帮到你。感谢阅读。

文章来源:https://dev.to/mpermar/how-to-create- effective-pull-requests-2m8e
PREV
何时使用 CSS Grid 以及何时使用 Flexbox 进行多行布局
NEXT
金丝雀部署 部署策略简介:蓝绿部署、金丝雀部署等