[ English | 한국어 (대한민국) | Indonesia | 中文 (简体, 中国) | español (México) | English (United Kingdom) | Deutsch ]

如何成为补丁高手?

当你致力于实现新功能或为现有功能添加文档时,很容易沉浸在工作中,而忘记了构建更改的潜在规则。

本节将指导你如何创建人们愿意审查的补丁。

使你能够

  • 了解如何构建一个补丁,使其在审查过程中更易于维护

  • 了解如何构建一个补丁,使其更易于社区成员审查

合适的尺寸

审查大型补丁非常不方便且耗时,因此我们始终建议将你的更改分解为更小的块。

虽然没有神奇的数字,但尽量保持更改的尺寸尽可能小,但总的更改行数应在几百行以内。包含大量测试但代码更改很少的补丁,其工作量与代码更改量大的补丁一样。

在极少数情况下,如果无法对更改进行良好的逻辑分解,并且你的补丁可能会增长到一千行或更多行。在某些情况下,这是可以接受的,因为你无法将相关的测试更改提取到另一个补丁中,例如,但这并不推荐。

始终尝试将尽可能多的内容提取到其他补丁中,例如文档或功能逻辑部分,这些部分不依赖于较低层中的通用函数。

较长的补丁需要更多的时间来审查;无论你做什么,都要保持长度合理。如果无法做到,你可以通过添加代码注释并编写详细的提交消息来描述你在补丁中引入的更改,从而帮助审查者。

补丁链、Depends-On 标签和 Gerrit 主题

在复杂的特性实现工作时,当你需要对同一项目的多个模块或多个项目引入更改时,你需要小心管理依赖关系。

根据你的设计结构,你可以选择多种选项。你可以将更改组织成补丁链,也可以使用“Depends-On”标签。

Depends-On 标签

当你在多个项目仓库中进行更改时,你可以使用“Depends-On”标签标记依赖补丁。该标签将作为提交消息中的链接出现,这可以帮助你和审查者跟踪和导航你的更改的依赖关系。

“Depends-On”标签是你的更改上的一个标记,当使用时,补丁不能被合并,直到它的所有依赖项都已合并。

该标签也可以应用于针对同一仓库的补丁。在这种情况下,更改是足够独立的,可以保持独立,这意味着如果你需要修复审查评论中的更改,你可以逐个补丁地进行修复。这对于每个补丁的重新基准也适用。

注意

如果你使用“Depends-On”标签,你需要下载一个特性实现或文档更改的所有更改,才能测试该特性或使用应用所有更改的文档进行构建。在这种情况下,Git 不会自动处理依赖关系。

补丁链

在某些情况下,当你将所需的更改分解为更小的块时,你无法避免它们之间的直接依赖关系,这会阻止你拥有独立的更改。你需要将你的更改组织成一个链条,以维护依赖关系,这需要在你使用这些更改时需要格外小心。

即使你有一系列补丁,你仍然需要将代码更改和相关的测试放在一个补丁中,因为你无法保证它们都能及时合并到发布中。

当你有一个链条时,Gerrit 会通过在 Gerrit UI 的右上角的“相关更改”列中列出所有提交标题来帮助你。这些标题也是链接,可以帮助你导航到更改以进行审查,当你上传新版本时。

如何处理链条?

如果你记住一些建议,处理补丁链会很容易

  • 始终为这些更改保留一个本地分支,以确保你不会将其与其他功能或错误修复相关的更改混淆。

  • 始终将链条视为一个更改块,通过重新基准整个链条并保持更新,当你修改补丁以修复审查评论或添加更改时。

  • 要修改链条中的补丁,你需要使用交互式重新基准

git rebase -i HEAD^

你需要像从链条顶部开始一样多的“^”符号,来编辑你想要编辑的补丁的编号。或者,你可能希望使用 git-restack,它会为你计算适当的 git rebase 命令。

Gerrit 还为你提供了编辑补丁本身或仅编辑提交消息以及更多高级更改选项,例如修改作者。

  • 要下载完整的链条,你需要下载顶部补丁,Git 会自动下载链条中的所有依赖补丁。

  • 如果你只需要修改链条中的顶部补丁,则可以像更新单个补丁一样进行操作。

  • 当你上传链条中的更改时,只有更新的补丁会被上传。这也意味着链条中较低补丁的审查分数不会受到影响。

  • 始终检查你对每个补丁所做的更改,并小心地确保你将更改应用于正确的补丁,因为补丁仍然会单独合并,并且不能保证整个链条会同时合并。

有关管理补丁链的更深入了解,请参阅 教程:以系列形式开发更改

Gerrit 主题

你可以在上传更改以供审查时指定更改的主题。虽然 Gerrit 主题不会为你的补丁添加依赖关系,但你可以应用基于主题的搜索,这将显示所有项目中与相同主题相关的更改。Gerrit 也会在审查页面的右上角的“相同主题”列中向你显示它们。

这是一种帮助跟踪相关更改的好方法,无论它是功能实现、错误修复还是文档工作。

如何构建你的更改?

当你的工作项超过特定大小,并且你需要上传多个补丁时,无论是在补丁链还是独立更改的情况下,构建它都至关重要。

在项目中按模块分组更改是一个好的做法,例如,在 OpenStack Compute 中,virt 驱动程序更改、计算管理器和 api 更改。

通过按模块分组更改,你还可以通过组件的层次结构构建链条或依赖关系,并始终将 API 更改放在最后,因为这将启用新功能,并且该更改将依赖于你为设计所触及的所有其他内容。

除此之外,你还可以查看功能以找到更小的构建块,并使你的更改更小。例如,可以先实现对对象的更改,然后在实现新的 API 功能时使用它。

更改的结构化拆分

创建良好提交的首要规则是确保每个提交只有一个“逻辑更改”。有许多原因说明这是一个重要的规则

  • 更改的代码量越小,审查和识别潜在缺陷就越快、越容易。

  • 如果稍后发现更改存在缺陷,可能需要撤消有问题的提交。如果其他无关代码更改与原始提交纠缠在一起,则执行此操作会容易得多。

  • 在使用 Git 的 bisect 功能进行问题排查时,定义良好的小更改也有助于隔离代码问题出现的确切位置。

  • 当使用 git annotategit blame 浏览历史记录时,定义良好的小更改也有助于隔离代码来自何处以及为什么。

正确的内容

与任何功能实现或错误报告无关的更改可以上传,但审查者不太欢迎它们。

改进代码或文档应该是一项更大的努力的一部分,例如,如果你想修复文档中的错别字,你应该对整个指南进行修复。也更喜欢报告一个包含可以稍后跟踪的任务的工作项的故事。

代码改进也是如此。由于社区庞大且遍布全球,我们有编码指南,但每个人的风格仍然可能大相径庭。我们不强制执行特定的编码风格,因此与修复相关的更改不太受欢迎,并且是应该避免的非常主观的争论的来源。

对于通过重构方法和删除未使用的代码片段使代码更具可读性和更易于维护的代码重构工作,强烈建议先咨询项目团队并在 StoryBoard 中报告一个故事,然后将相关的更改上传到 Gerrit 进行审查。