在 Git 中创建完美的提交

Avatar of Tobias Günther
Tobias Günther

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 200 美元的免费积分!

本文是我们“高级 Git”系列的一部分。 请务必关注 Tower 的 Twitter注册 Tower 时事通讯 以了解下一篇文章的信息!

Git 中的提交可以是以下两种情况之一

  • 它可以是来自各种主题的更改的杂乱组合:一些用于错误修复的代码行、重写旧模块的尝试以及几个用于全新功能的新文件。
  • 或者,通过一点小心,它可以帮助我们掌握事态。 它可以成为属于一个且仅一个主题的相关更改的容器,从而使我们更容易理解发生了什么。

在这篇文章中,我们讨论了产生后一种提交类型需要什么,或者换句话说:“完美”的提交。

高级 Git 系列

  1. 第 1 部分: 在 Git 中创建完美的提交您在此处!
  2. 第 2 部分: Git 中的分支策略
  3. 第 3 部分: 通过拉取请求实现更好的协作
  4. 第 4 部分: 合并冲突
  5. 第 5 部分: 变基与合并
  6. 第 6 部分: 交互式变基
  7. 第 7 部分: 在 Git 中挑选提交
  8. 第 8 部分: 使用 Reflog 恢复丢失的提交

为什么整洁且细粒度的提交很重要

是否真的有必要以谨慎、周到的方式编写提交? 我们能否将 Git 视为一个无聊的备份系统? 让我们再次回顾一下上面的示例。

如果我们遵循第一条路径——在每次发生更改时都将更改塞进提交中——提交就会失去大部分价值。 一个提交与下一个提交之间的分离变得随意:似乎没有理由将更改放入一个提交而不是另一个提交中。 稍后查看这些提交,例如,当您的同事试图理解该修订版中发生了什么时,就像翻阅每个家庭都拥有的“杂物抽屉”一样:这里面有所有在其他地方找不到的东西,从蜡笔到图钉和收据。 在这些抽屉里找东西非常困难!

遵循第二条路径——我们只将属于同一提交的内容(即更改)放入同一提交中——需要更多的计划和纪律。 但最终,您和您的团队会获得非常有价值的东西:一个干净的提交历史! 这些提交可以帮助您了解发生了什么。 它们有助于以易于理解的方式解释所做的复杂更改。

我们如何创建更好的提交?

编写更好的提交

一个概念对于在 Git 中编写更好的提交至关重要:暂存区

暂存区正是为此目的而创建的:允许开发人员以非常细粒度的方式选择应包含在下一次提交中的更改。 而且,与其他版本控制系统不同,Git 强制您使用此暂存区。

但是,不幸的是,仍然很容易忽略暂存区的整理效果:一个简单的 git add . 将获取所有当前的本地更改,并将其标记为下一次提交。

确实,这有时可能是一种非常有用且有效的方法。 但很多时候,我们最好停下来思考一下,我们所有的更改是否确实都与同一个主题有关。 或者两个或三个单独的提交是否可能是一个更好的选择。

在大多数情况下,保持提交比更大的提交小得多是有意义的。 它们专注于单个主题(而不是两个、三个或四个),因此往往更易于阅读。

暂存区允许我们仔细挑选应包含在下一次提交中的每个更改:

$ git add file1.ext file2.ext

这只会将这两个文件标记为下一次提交,并将其他更改保留在以后的提交或进一步编辑中。

这种暂停并刻意选择什么应该进入下一次提交的简单行为意义重大。 但我们还可以做得更精确。 因为有时,即使单个文件中的更改也属于多个主题。

让我们看一个真实的例子,并查看“index.html”文件中的确切更改。 我们可以使用“git diff”命令或像Tower这样的 Git 桌面 GUI

现在,我们可以将 -p 选项添加到 git add

$ git add -p index.html

我们指示 Git 在“补丁”级别遍历此文件:Git 手把手地引导我们遍历此文件中的所有更改。 并且它会询问我们,对于每个块,我们是否要将其添加到暂存区。

通过为第一个块键入 [Y](表示“是”)并为第二个块键入 [N](表示“否”),我们可以将此文件中的更改的第一部分包含在下一次提交中,但将其他更改保留在以后或进行更多编辑。

结果如何? 一个更细粒度、更精确的提交,专注于单个主题。

测试您的代码

由于我们在这里讨论的是“完美的提交”,因此我们不能忽略测试主题。 您“测试”代码的确切方式当然可能会有所不同,但测试很重要这一概念并不新鲜。 事实上,许多团队拒绝将未经适当测试的代码视为已完成的代码。

如果您仍然对是否应该测试代码犹豫不决,让我们消除一些关于测试的神话

  • “测试被高估了”:事实是,测试可以帮助您更快地发现错误。 最重要的是,它们可以帮助您在某些内容进入生产环境之前发现错误——因为这是错误造成最大伤害的时候。 而尽早发现错误,毫不夸张地说,是无价的!
  • “测试会浪费宝贵的时间”:一段时间后,您会发现编写良好的测试可以让您更快地编写代码。 您会花费更少的时间来查找错误,并且会发现,更常见的是,结构良好的测试也会为您实际的实现做好准备。
  • “测试很复杂”:虽然这在几年前可能是一个论点,但现在并非如此。 大多数专业的编程框架和语言都提供了广泛的支持来设置、编写和管理测试。

总而言之,将测试添加到您的开发习惯中几乎可以保证使您的代码库更加健壮。 同时,它们还能帮助您成为一名更好的程序员。

有价值的提交信息

使用 Git 进行版本控制并不是一种花哨的备份代码方式。 而且,正如我们已经讨论过的,提交不是任意更改的转储。 提交的存在是为了帮助您和您的团队成员了解项目中发生了什么。 而一个好的提交信息对于确保这一点大有帮助。

但是,什么构成了一个好的提交信息?

  • 一个简短且简洁的主题行,总结了更改
  • 一个描述性的消息正文,解释了最重要的内容(并尽可能简洁)

让我们从主题行开始:目标是获得发生情况的简要摘要。 当然,简洁是一个相对的概念; 但一般的经验法则是(理想情况下)将主题保持在 50 个字符以内。 顺便说一句,如果您发现自己难以想出一个简短的内容,这可能表明提交处理了太多主题! 值得再次查看一下,看看您是否需要将其拆分为多个单独的主题。

如果您在主题后面加上换行符和一个额外的空行,Git 会理解以下文本是消息的“正文”。 在这里,您有更多空间来描述发生了什么。 记住以下问题会有所帮助,您的正文应旨在回答这些问题

  • 此提交对您的项目进行了哪些更改?
  • 进行此更改的原因是什么?
  • 是否有任何需要注意的事项? 其他人需要了解有关这些更改的任何信息?

如果您在编写提交信息正文时牢记这些问题,您很可能会产生对发生情况的有用描述。 最终,这会在尝试理解此提交时使您的同事(以及一段时间后的您)受益。

除了我刚才描述的关于提交信息内容的规则外,许多团队也关心格式:就字符限制、软或硬换行等达成一致,都有助于在团队内创建更好的提交。

为了更容易遵守此类规则,我们最近在我们制作的 Git 桌面 GUI Tower中添加了一些功能:例如,您现在可以根据自己的喜好配置字符计数或自动换行。

优秀的代码库源于优秀的提交

任何开发者都会承认他们想要一个优秀的代码库。但要实现这一崇高目标,只有一个途径:持续创建优秀的提交!我希望我已经证明了 (a) 追求这个目标绝对值得,并且 (b) 实现它并不那么难。

如果你想深入了解高级 Git 工具,请随时查看我的(免费!)“高级 Git 工具包”:它包含一系列关于分支策略、交互式变基、Reflog、子模块等等主题的短视频。

祝你创建出色的提交!

高级 Git 系列

  1. 第 1 部分: 在 Git 中创建完美的提交您在此处!
  2. 第 2 部分: Git 中的分支策略
  3. 第 3 部分: 通过拉取请求实现更好的协作
  4. 第 4 部分: 合并冲突
  5. 第 5 部分: 变基与合并
  6. 第 6 部分: 交互式变基
  7. 第 7 部分: 在 Git 中挑选提交
  8. 第 8 部分: 使用 Reflog 恢复丢失的提交