清理 Git 历史记录

2021-08-09 02:59:19

干净的 git 提交历史通常被低估,对于简化代码审查和理解未来的变化(可能在停机期间)非常有用。当然,我们在这里讨论的是提交到共享存储库的最终历史记录,而不是我们处理代码时的中间历史记录。有时中间历史足以直接推送,但这实际上相当罕见。清理历史记录一开始可能看起来很乏味,只是为了获得微不足道的美容效果,但随着实践,它会变得更容易、更快。在这里,我收集了一些在将 git 提交历史发布给其他人之前清理它的技巧,例如以拉取请求的形式。另一个清理历史记录的好时机是在合并之前,如果我们添加了额外的提交来处理审查评论。不要合并只是为了解决评论而存在的提交,修复原始的错误提交。干净的提交历史是仅包含良好提交的历史。但是什么使提交好呢?这有两部分,提交的内容和提交描述。提交消息有很多标准,但我个人使用 OTP 提交指南作为基础。然后我尝试在消息中包含任何重要的技术和产品考虑因素,例如更改的动机,以及技术上的细微差别,例如考虑的替代实现和权衡。参见 Dan Carley 的惊人例子。提交的内容有点模糊,但这是我要寻找的:每个提交本身都应该有意义。提交的大小恰到好处,无需添加任何内容,也无需删除任何内容。我们希望在每次提交中添加/删除/更改一件事。如果我们努力想出一个好的提交摘要,那就暗示我们的提交范围不明确。理想情况下,这意味着审查者可以逐个提交审查我们的更改。我们尝试在提交中讲述一个故事。

每个提交都应该是可运行的,也就是说我们应该能够 gitcheckout 任何提交并获得一个功能性的代码库。这意味着没有“WIP”提交或仅在最后恢复功能的提交链。这很重要,这样我们就可以在事情横向发展时恢复或回滚任何提交。 Git 非常灵活,对于这里描述的许多技术,有执行相同操作的更快方法。我正在描述多步方法,这些方法可以将多个单独的提交保留更长的时间,因为合并两个提交比拆分单个提交容易得多。具体来说,在我进行最终的交互式 rebase 以解决所有更改之前,我对历史进行了大量修补,在此处结合了其中的几种技术。这样我就可以在中途改变主意,而不会在撤消任何事情时遇到任何麻烦。我们还将所有标志的长版用于教育目的。有关简短版本,请参阅手册页。交互式变基非常强大,可用于执行许多不同的操作。我们可以使用它来避免记住许多其他专门为做一件事而量身定制的命令。它通常也不同于常规的变基,我们将一个或多个提交移动到不同的基础上(因此变基)。当以交互方式变基时,我们通常希望编辑 HEAD 和 <ref> 之间的所有提交。因此,我们需要选择 <ref> 作为我们要编辑的范围的另一端。当您启动交互式变基时,将在 $EDITOR 中打开一个特殊文件,其中包含变基范围内的所有提交和对它们的操作。 Git 将在描述可用操作的列表下方插入一个指南。一旦我们对行动感到满意,我们就会确认计划并解决行动。想想棋盘游戏或纸牌游戏。虽然我鼓励在提交时直接编写完整的提交消息,但有时我们可以考虑对早期提交消息进行添加或更改。要仅更改现有提交的提交消息,我们可以使用:

这些命令会创建附加到我们历史记录末尾的附加“修复提交”。它们中的每一个都通过其标题链接到另一个提交。为了实际将两者(或更多)结合起来,我们使用: 这应该设置交互式 rebase 来做正确的事情,所以我们只需通过保存和关闭文件来确认建议的操作。让我们假设我们已经写了一个提交,然后注意到这个提交范围内的一个小改动。我们只想修复现有的提交,而不是编写新的提交。只需运行以下命令即可完成:如果我们仅在添加其他提交后才发现错误,并且想要追溯添加对较早提交的更改,则此命令变为: 和以前一样,这将创建可以与交互式变基结合的修复提交和 --autosquash 标志。如果我们希望将历史记录中已有的两个提交合并为一个,我们可以使用交互式 rebase,如果需要,将第二个提交移到第一个提交之后,然后选择压缩选项。在解决 rebase 时,git 将在此时停止并为我们打开一个组合提交消息。我们肯定要编辑这个,而不是坚持使用两条原始消息的默认连接。

如果我们想更改提交的顺序,您已经猜到了,我们可以通过交互式 rebase 来实现,只需更改列表中提交的顺序即可。如果一个提交结果包含几个独立的更改,我们可以选择拆分提交以隔离这些更改。我们再次使用交互式变基,但这次我们为要拆分的提交选择编辑操作。当我们到达此提交时,这将导致 rebase 暂停。在这一点上,我们要使用增量添加文件的部分。这在编辑现有文件时效果最好,因为补丁界面有点缺乏,但它有效。那里的 Emacs 用户可能会熟悉非常出色的 Magit 界面,它可以轻松地对各个行进行分段。然后我们可以使用它来创建新的提交。一旦我们完成创建新提交替换旧提交,我们可以使用如果我们发现自己有一个我们决定不再需要的提交,我们可以简单地从历史记录中删除它。这可能是我们所做的更改,但后来意识到我们根本不需要,或者类似于 GitHub“更新分支”合并提交噪音。最简单的方法是使用交互式 rebase 并为相关提交选择放置操作。 git 手册页按命令拆分,因此有关 gitrebase 的文档,请查看 man git-rebase。手册页很好,但更多的是参考而不是使用指南。

哦该死,吉特!?!有一个令人难忘的域,并提供了一些关于如何在发生大量 git 事故后进行自救的信息。