在Git中,一个提交可能是两种情况之一。
- 它可以是各种主题的杂乱无章的改动:一些修复错误的代码行,重写一个旧模块的尝试,以及为一个全新的功能编写的几个新文件。
- 或者,只要稍加注意,它可以成为帮助我们保持领先的东西。它可以成为一个容器,用来存放属于一个且仅属于一个主题的相关变化,从而使我们更容易理解发生了什么。
在这篇文章中,我们将讨论如何产生后一种类型的提交,或者换句话说:"完美 "的提交。
高级Git系列。
- 第一部分。 在Git中创建完美的提交
你在这里! - **第2部分:**Git中的分支策略
即将推出! - **第三部分:**用拉动请求进行更好的协作
- **第四部分:**合并冲突
- **第五部分:**重置与合并
- **第六部分:**交互式重做
- **第七部分:**在Git中挑选提交的内容
- 第8部分:在Git中挑选提交使用重新记录来恢复丢失的提交
为什么干净和细化的提交很重要
真的有必要以一种仔细、周到的方式组成提交吗?难道我们就不能把 Git 当作一个无聊的备份系统吗?让我们再重温一下上面的例子。
如果我们遵循第一条路径--只要有改动就塞进提交,那么提交就失去了很多价值。一个提交和下一个提交之间的分离变得很随意:似乎没有理由把改动放在一个提交而不是另一个提交中。以后再看这些提交,比如当你的同事想弄清楚那个修订中发生了什么时,就像翻看每个家庭都有的 "抽屉 "一样:这里有所有在其他地方找不到的东西,从蜡笔到摁扣和现金单。要在这些抽屉里找到东西是非常困难的!

走第二条路--我们只把属于自己的东西(读作:变化)放进同一个承诺--需要更多的计划和纪律。但最终,你和你的团队会得到一些非常有价值的东西:一个干净的提交历史!这些提交可以帮助你了解发生了什么。这些提交可以帮助你了解发生了什么。它们有助于以一种可消化的方式解释所做的复杂修改。

我们该如何创建更好的提交呢?
编写更好的提交
在 Git 中,有一个概念是编写更好的提交的核心: 暂存区。
暂存区域正是为了这个目的而设立的:允许开发者以非常细化的方式选择应该成为下一次提交内容的修改。而且,与其他版本控制系统不同的是,Git 迫使你使用这个暂存区。
然而不幸的是,我们还是很容易忽视暂存区域的整理作用:一个简单的git add . ,就能把我们当前所有的本地修改标记为下一次提交。
诚然,这有时是一个非常有帮助和有效的方法。但很多时候,我们最好先停下来,决定我们所有的修改是否真的是关于同一个主题。或者说,两个或三个独立的提交可能是一个更好的选择。
在大多数情况下,让提交的内容更小而不是更大是非常有意义的。专注于一个单独的主题(而不是两个、三个或四个),它们往往更具有可读性。
Staging Area(暂存区)允许我们仔细挑选每一个应该进入下一次提交的改动。
$ git add file1.ext file2.ext
这将只为下一次提交标记这两个文件,而将其他修改留给未来的提交或进一步的编辑。
这个简单的暂停动作,并刻意选择应该进入下一次提交的内容,可以起到很好的作用。但我们可以做得更精确些。因为有时候,即使是一个文件中的修改也属于多个主题。
让我们看一个真实的例子,看看我们的 "index.html "文件中的确切变化。我们可以使用 "git diff "命令或者像Tower这样的Git桌面GUI。

现在,我们可以在git add 中添加-p 选项。
$ git add -p index.html
我们正在指示Git在 "补丁 "层面上浏览这个文件。Git 牵着我们的手,带领我们浏览这个文件中的所有改动。它还会问我们,对于每一个块,我们是否要把它添加到暂存区。

在第一块输入[Y] (代表 "是"),在第二块输入[N] (代表 "否"),我们就可以在下一次提交中包括我们在这个文件中的第一部分修改,而把其他的修改留给以后或更多的编辑。
结果是什么?一个更细化、更精确的提交,专注于一个主题。
测试你的代码
既然我们在这里讨论的是 "完美的提交",我们就不能忽视测试的话题。你到底如何 "测试 "你的代码,当然可以有不同的方式,但测试很重要的概念并不新鲜。事实上,如果一段代码没有经过适当的测试,许多团队拒绝认为它已经完成。
如果你对是否应该测试你的代码还犹豫不决,让我们来揭穿几个关于测试的神话。
- **"测试被高估了"。**事实是,测试可以帮助你更快地发现错误。最重要的是,它们可以帮助你在产品进入生产阶段之前发现它们,而这正是错误伤害最大的时候。毫不夸张地说,尽早发现错误是无价之宝。
- **"测试需要花费宝贵的时间"。**一段时间后,你会发现写得很好的测试使你写代码更快。你浪费了更少的时间去寻找错误,并且发现,更多的时候,一个结构良好的测试也为你的实际执行提供了思路。
- **"测试很复杂"。**虽然这在几年前可能是一个论点,但现在这不是事实。大多数专业的编程框架和语言都为设置、编写和管理测试提供了广泛的支持。
总而言之,在你的开发习惯中加入测试,几乎可以保证使你的代码库更加强大。同时,它们还能帮助你成为一个更好的程序员。
有价值的提交信息
使用Git的版本控制并不是一种备份代码的花哨方式。而且,正如我们已经讨论过的,提交并不是任意修改的转储。提交是为了帮助你和你的队友了解项目中发生的事情。一条好的提交信息可以很好地保证这一点。
但怎样才能写出一条好的提交信息呢?
- 简明扼要的主题行,概述修改内容
- 描述性的信息正文,解释最重要的事实(而且要尽可能的简洁)
让我们从主题行开始:目标是对所发生的事情做一个简短的总结。当然,简洁是一个相对的术语;但一般的经验法则是(最好)将主题保持在50个字符以下。顺便说一句,如果你发现自己很难想出一些简短的东西,这可能是一个指标,表明该承诺处理了太多的主题!这可能值得重新考虑。不妨再看一下,看看是否需要将其分成多个独立的主题。
如果你用一个换行符和一个额外的空行来结束主题,Git 会理解下面的文本是信息的 "主体"。在这里,你有更多的空间来描述发生了什么。牢记以下问题会有所帮助,你的正文应该以回答这些问题为目标。
- 你的项目在这次提交中发生了什么变化?
- 做这个改动的原因是什么?
- 有什么特别需要注意的地方吗?关于这些变化,还有什么需要别人知道的吗?
如果你在写提交信息正文时牢记这些问题,你就很有可能对所发生的事情做出有用的描述。而这最终会使你的同事(以及一段时间后的你)在试图理解这次提交时受益。
除了我刚才所说的关于提交信息内容的规则外,许多团队还关心提交信息的格式:就字符限制、软行或硬行包装等达成一致,都有助于在团队中产生更好的提交。
为了让大家更容易遵守这些规则,我们最近为我们制作的Git桌面GUI--Tower增加了一些功能:例如,你现在可以随意配置字符数或自动换行了。

一个伟大的代码库由伟大的提交组成
任何开发者都会承认,他们希望有一个伟大的代码库。但要实现这个崇高的目标,只有一个办法:持续不断地产生伟大的提交!我希望我能够证明这一点。我希望我能够证明:(a)绝对值得追求这个目标;(b)实现这个目标并不难。
如果你想深入了解先进的 Git 工具,可以看看我的(免费的!)"Advanced Git Kit":它是一个简短的视频集,主题包括分支策略、Interactive Rebase、Reflog、Submodules 以及更多。
祝你在创建令人敬畏的提交时愉快