Git 正确使用文档

作者:Zack Brown

Jonathan Corbet 撰写了一份文档,旨在纳入内核树,描述了基于 git 的内核仓库合并和变基的最佳实践。正如他所说,它代表了当前实际使用的工作流程,并且是一份鲜活的文档,有望随着时间的推移得到补充和修正。

这份文档的灵感来自于注意到 Linus Torvalds 经常对其他人(通常是子系统维护者)处理他们的 git 树的方式感到不满。

有趣的是,请注意在 Linus 编写 git 工具之前,分支和合并在开源世界中几乎闻所未闻。在 CVS 中,它简直是一场由吸血和破碎魔法构成的噩梦。其他工具也好不到哪里去。git 背后的主要动机之一——除了闪电般的速度——实际上是为了使分支和合并成为微不足道的操作——而它们也确实变成了这样。

Jonathan 写道,分支和合并的副产品之一是变基——更改本地仓库的补丁历史。变基的好处非常棒。它们可以使仓库历史更清晰明了,从而更容易追踪引入特定错误的补丁。因此,变基对开发过程具有直接价值。

另一方面,如果使用不当,变基可能会造成很大的混乱。例如,假设您对已经与另一个仓库合并的仓库进行变基,然后再将它们再次合并——简直是灵魂的死亡。

因此,Jonathan 解释了一些好的经验法则。永远不要对已经共享的仓库进行变基。永远不要对来自其他人仓库的补丁进行变基。总的来说,除非有真正的原因,否则永远不要变基。

由于变基会更改补丁的历史,因此它依赖于一个新的“基础”版本,后来的补丁从该版本开始分叉。Jonathan 建议选择通常被认为更稳定而不是更不稳定的基础版本——例如,新版本或候选发布版本,而不是仅仅是常规开发期间的任意补丁。

Jonathan 还建议,对于任何变基,都应将所有变基的补丁视为新代码,并进行彻底测试,即使它们在变基之前已经过测试。

他说:“如果变基仅限于私有树,提交基于众所周知的起点,并且经过良好测试,那么出现问题的可能性很低。”

转到合并,Jonathan 指出,近 9% 的内核提交是合并。仅在 5.1 开发周期中就有超过 1,000 个合并请求。

他在文档中指出,尽管“许多项目要求拉取请求中的分支基于当前主干,以便历史记录中不出现合并提交”,但内核没有这样的要求。合并被认为是完全有序的业务方式,开发人员不应尝试对其分支进行变基以避免合并。

内核开发的一个有趣之处在于,维护层级倾向于支持 git 仓库维护者的层级结构。一个人或几个人管理分支内核仓库,并让开发人员管理该树的分支,而其他开发人员又反过来管理这些分支的分支,这并不罕见。

对于中层维护者,Jonathan 指出,有两种相关情况:将层级较低的树合并到您自己的树中,以及将您自己的树合并到 Linus 的顶层树中。

Jonathan 建议,对于从中层树接受合并的中层维护者,维护者不应试图隐藏合并请求,实际上,应该添加提交消息或变更日志条目,解释合并中包含的补丁。

Jonathan 还指出,“Signed-Off-By”标签是提交消息的关键要素,有助于追踪责任以及重要的调试信息。他建议所有维护者都应继续使用它们,并在从其他树合并时验证它们。Jonathan 说:“不这样做会威胁到整个开发过程的安全性。”

该建议指的是下游树,但 Jonathan 对从上游树合并提出了一些非常有趣的观点。这是当您在自己的树上工作时,并且您想确保自己与 Linus 或与他关系密切的人的最新和最出色的树保持同步。当然,这样做会让您自己的生活稍微轻松一些,因为您将是最新的,您可以针对树的尖端测试您的代码等等。尽管如此,Jonathan 还是建议不要这样做。

一方面,您可能会将其他人的错误带入您自己的树中,破坏您的测试代码的稳定性,然后您将不确定您的代码是否真的可靠并准备好进一步向上游提交。

另一个诱惑是在提交您自己的合并请求之前,从上游来源进行合并,以确保您的请求不会遇到任何冲突。然而,正如 Jonathan 所说,“Linus 坚决认为,他宁愿看到合并冲突,也不愿看到不必要的反向合并。看到冲突让他知道潜在的问题区域在哪里。他做了很多合并(在 5.1 开发周期中为 382 次),并且非常擅长解决冲突——通常比相关开发人员更好。”

相反,如果您确实注意到当 Linus 进行合并时会出现冲突,您应该在拉取请求中说明一下,以便 Linus 看到您看到了这种情况。

作为最后的手段,对于特别棘手的情况,Jonathan 说,您可以创建另一个分支,其中包含您自己的冲突解决方案,并将 Linus 指向该分支,以便他可以看到您将如何自行解决问题。但是,拉取请求应该是针对未解决的分支。

他说,以这种方式进行测试合并是可以的。它可以帮助您了解是否会发生任何冲突,以便您可以更好地与上游维护者沟通。

他提供了一些更好的建议,并总结说

上面列出的指南只是一些指南。总会有一些情况需要不同的解决方案,这些指南不应阻止开发人员在需要时做正确的事情。但是,人们应该始终考虑是否真的需要出现这种情况,并准备好解释为什么需要做一些不正常的事情。

而且……Linus 回复说他喜欢整个文档。

来自 GoogleDavid Rientjes 报告说,他实际上一直在编写一份内部文档,供 Google 工程师使用,讨论的就是这个话题。他很高兴 Jonathan 在解释方面做得比他自己努力的更好。

Geert Uytterhoeven 也喜欢这份新文档,他提供了一些拼写和语法更正。

只有 Theodore Ts'o 提出了任何重要的批评。他认为应该明确区分补丁重新排序(他认为这是大多数人在谈论变基时想到的)与实际更改或删除已进入树的提交。两者在技术上都是变基,但两者实际上是非常不同的操作。

Jonathan 回复说,建议文档可以分别提及“变基”和“历史修改”。Ted 同意这样做会更好。

线程结束。我很高兴看到这种文档进入内核。它与通用的 git 建议不同,因为它特定于内核开发流程和已制定的策略。与此同时,它可能对其他可能想要模仿 Linux 内核开发过程的大型项目非常有用。所有开源项目本质上都在模仿内核开发过程——Linus 是第一个发现并普及如何运行开源项目的方法的人——而且即使在现在,他的开发政策决策中也往往蕴含着很多智慧。

注意:如果您在上面被提及并想在评论区上方发布回复,请将包含您的回复文本的消息发送至 ljeditor@linuxjournal.com。

Zack Brown 是 Linux JournalLinux Magazine 的技术记者,并且曾是每周新闻通讯“Kernel Traffic”和“Learn Plover”速记打字教程的作者。他于 1993 年在他的 386 电脑上安装了 Slackware Linux,配备了 8MB 内存,并被开源社区彻底震撼。他是纯策略棋盘游戏 Crumble 的发明者,您可以用几块纸板自己制作。他还喜欢写小说、尝试动画、改革拉班舞谱、设计和缝制自己的衣服、学习法语以及与朋友和家人共度时光。

加载 Disqus 评论