引言

这篇文章我翻译自How to Write a Git Commit Message,由于文章篇幅太多,全部翻译下来太浪费时间了,因此我把一些重要的地方全部翻译完了,如果英语好的请读原文,英语水平不算太好地同学,可以参考我的翻译来理解原文。如果大家能把我翻译的部分看完,相信大家就可以写出一个好的commit信息了。这篇文章主要介绍的是写好Git的commit信息我们需要遵守的一些规则并说明为什么好的commit信息是如此重要,作者都给出了很好地解释。

文章作者的Github主页为:https://github.com/cbeams,从他的主页可以看出他是spring-framework和gradle的contributor.

为什么好的commit信息如此重要?

如果你去随便找几个Git仓库的日志,你会发现这些仓库的commit信息或多或少地有些混乱。举个例子,大家来看一看我前些日子提交到Spring代码的commit日志:

$ git log --oneline -5 --author cbeams --before "Fri Mar 26 2009"e5f4b49 Re-adding ConfigurationPostProcessorTests after its brief removal in r814. @Ignore-ing the testCglibClassesAreLoadedJustInTimeForEnhancement() method as it turns out this was one of the culprits in the recent build breakage. The classloader hacking causes subtle downstream effects, breaking unrelated tests. The test method is still useful, but should only be run on a manual basis to ensure CGLIB is not prematurely classloaded, and should not be run as part of the automated build.
2db0f12 fixed two build-breaking issues: + reverted ClassMetadataReadingVisitor to revision 794 + eliminated ConfigurationPostProcessorTests until further investigation determines why it causes downstream tests to fail (such as the seemingly unrelated ClassPathXmlApplicationContextTests)
147709f Tweaks to package-info.java files
22b25e0 Consolidated Util and MutableAnnotationUtils classes into existing AsmUtils
7f96f57 polishing

呀!比较一下同一个仓库中最近刚刚提交的commit信息吧。

$ git log --oneline -5 --author pwebb --before "Sat Aug 30 2014"5ba3db6 Fix failing CompositePropertySourceTests
84564a0 Rework @PropertySource early parsing logic
e142fd1 Add tests for ImportSelector meta-data
887815f Update docbook dependency and generate epub
ac8326d Polish mockito usage

你更喜欢看哪个?前者在长度和形式上都有很大地不同; 而后者是简洁和一致的。前者是通常情况下都会出现的状况; 而后者绝不会偶然发生。然而许多仓库地日志都像前者,当然也有例外地,比如Git项目本身就是一个很好地例子。看看Spring Boot,或者是Tim Pope管理地仓库。

这些仓库地贡献者都知道一个构思好地commit信息是与开发同伴或未来的自己交流改动的最好方式。diff 命令会告诉你改动了什么,但是只有commit信息会告诉你为什么那样去改动。Peter Hutterer很好地解释了这点:

重新建立一段代码的背景情况是会浪费很多地时间。我们不能完全避免它,所以我们应该尽量去减少它。commit信息正好可以做到这点,因此,commit信息也可以表明一个开发者是否是个好地合作者。

If you haven’t given much thought to what makes a great Git commit message, it may be the case that you haven’t spent much time using git log and related tools. 这里有个恶性循环: because the commit history is unstructured and inconsistent, one doesn’t spend much time using or taking care of it. And because it doesn’t get used or taken care of, it remains unstructured and inconsistent.

But a well-cared for log is a beautiful and useful thing. git blame, revert, rebase, log, shortlog and other subcommands come to life. Reviewing others’ commits and pull requests becomes something worth doing, and suddenly can be done independently. Understanding why something happened months or years ago becomes not only possible but efficient.

A project’s long-term success rests (among other things) on its maintainability, and a maintainer has few tools more powerful than his project’s log. It’s worth taking the time to learn how to care for one properly. What may be a hassle at first soon becomes habit, and eventually a source of pride and productivity for all involved.

In this post, I am addressing just the most basic element of keeping a healthy commit history: how to write an individual commit message. There are other important practices like commit squashing that I am not addressing here. Perhaps I’ll do that in a subsequent post.

Most programming languages have well-established conventions as to what constitutes idiomatic style, i.e. naming, formatting and so on. There are variations on these conventions, of course, but most developers agree that picking one and sticking to it is far better than the chaos that ensues when everybody does their own thing.

一个团队对于commit日志地方法应该相同。为了创建更有用地版本历史,一个团队首先应该统一定义commit信息地规范。这需要至少定义下面3件事情:

Style. 标记语法, 行间距, 语法, 大写字母开头, 标点符号. 阐明这些事情, 不要去臆测,让一切尽可能地简单。最终将会使日志出奇地
一致,这不仅仅会使大家很乐意去读,而且会使大家经常性地去读日志。

Content. commit信息的主体(如果有的话)应该包含什么样的信息?它不应该包含什么?

Metadata. How should issue tracking IDs, pull request numbers, etc. be referenced?

Fortunately, there are well-established conventions as to what makes an idiomatic Git commit message. Indeed, many of them are assumed in the way certain Git commands function. There’s nothing you need to re-invent. 遵循下面的7条原则,你的committing方式会像一个专家一样。

优秀的Git commit信息遵循的七个规则

  1. 用一个空行分开主题与正文
  2. 限制主题行到50个字符
  3. 主题行用大写字母开头
  4. 主题行末尾不要用句号
  5. 主题行要用祈使语气
  6. 正文要在72个字符处时换行
  7. 用正文解释what 和 why 而不是how

For example:

Summarize changes in around 50 characters or lessMore detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as the
subject of the commit and the rest of the text as the body. The
blank line separating the summary from the body is critical (unless
you omit the body entirely); various tools like `log`, `shortlog`
and `rebase` can get confused if you run the two together.Explain the problem that this commit is solving. Focus on why you
are making this change as opposed to how (the code explains that).
Are there side effects or other unintuitive consequences of this
change? Here's the place to explain them.Further paragraphs come after blank lines.- Bullet points are okay, too- Typically a hyphen or asterisk is used for the bullet, precededby a single space, with blank lines in between, but conventionsvary hereIf you use an issue tracker, put references to them at the bottom,
like this:Resolves: #123
See also: #456, #789

上面例子中的文字详细地解释了很多原则,大家仔细看一下。

Separate subject from body with a blank line

对于一个commit信息来说,从开始到第一个空行被认为是commit头,这个头在Git中被广泛地使用。比如:Git-format-patch(1) 把commit信息转换成Email,主题行用作Email的标题,正文用作Email的body。

如果有些改动非常简单,那么这样的commit信息并不需要正文,只给一个主题行就行。比如下面的例子:

Fix typo in introduction to user guide

如果读者想要看看是怎样地改动的,他只需查看改动本身就可以的,比如用git show 或者 git diff 或者 git log -p 等命令。像这样不需要正文的commit,我们只需要用下面简单的方式commit就行:

$ git commit -m "Fix typo in introduction to user guide"

当一个改动比较复杂时,我们的commit就需要一些正文来解释我们做了什么和为什么这样去做?正文不要包含是怎样做的解释,因为代码本身就可以解释清楚,如果代码本身也不是很清楚,那么我们就应该对这段代码加上注释。比如下面的commit信息是按照我们的规则来写的:

Derezz the master control programMCP turned out to be evil and had become intent on world domination.
This commit throws Tron's disc into MCP (causing its deresolution)
and turns it back into a chess game.

一旦你日后重新浏览这些提交的信息时,你会发现这样严格要求格式是非常值得的。比如我们用下面的命令来浏览日志:

$ git log
commit 42e769bdf4894310333942ffc5a15151222a87be
Author: Kevin Flynn <kevin@flynnsarcade.com>
Date:   Fri Jan 01 00:00:00 1982 -0200Derezz the master control programMCP turned out to be evil and had become intent on world domination.This commit throws Tron's disc into MCP (causing its deresolution)and turns it back into a chess game.$ git log --oneline // 只显示主题行的内容
42e769 Derezz the master control program$ git shortlog
Kevin Flynn (1):Derezz the master control programAlan Bradley (1):Introduce security program "Tron"Ed Dillinger (3):Rename chess program to "MCP"Modify chess programUpgrade chess programWalter Gibbs (1):Introduce protoype chess program

Git中还有很多情况都会用到区分主题与正文,因此我们严格要求自己的commit信息格式是非常值得的。

Limit the subject line to 50 characters

50个字符并不是强制要求的,这仅仅是个经验法则。这个规则可以确保其可读性,并且会强制作者仔细思考一下,用一种更简明的方式来描述到底发生了什么?

Tip: 如果你很难用50个字符总结出到底发生了什么,那么你有可能一次提交了太多的变化。Strive for atomic commits .

Github的UI也完全意识到了这些规范,如果你的主题行超过了50个字符它会警告你:

Github会用省略符号截断超过72个字符地主题行:

因此最好达到50个字符的限制,但是把72个字符当作是严格的限制。

Capitalize the subject line

这个要求很简单。就是主题行要以大写字母开头。比如用下面的格式:

Accelerate to 88 miles per hour

下面的格式是不正确的:

accelerate to 88 miles per hour

Do not end the subject line with a period

主题行的末尾不要加句号。这是因为我们要保持主题行要少于50个字符,因此主题行的空间是很宝贵的。比如用下面的格式:

Open the pod bay doors

下面的格式是不正确的:

Open the pod bay doors.

Use the imperative mood in the subject line

主题行要用虚拟语气。虚拟语气意味着“口头上或者书面上就好像是给出一个命令或指令一样”。比如:

  • Clean your room
  • Take out the trash
  • Close the door

本屌丝的英语语法真的是很烂,因此去查了一下各种语气的表达方式,大家参考一下吧。

一、 陈述语气

陈述语气用来陈述事实或询问事情,用于陈述句,疑问句或感叹句中。

比如下面的语句:

  • The sun is larger than the earth.
  • Does Tom usually get up very early?
  • What a clever boy!

二、祈使语气

祈使语气表示劝告、命令、希望或禁止等,用原形动词开始,主语常被省略。

比如下面的语句:

  • Give me some candies first.

三、虚拟语气

虚拟语气用来表示说话人的主观愿望或假想,而不表示客观存在的事实,所说的是一个条件,不一定是事实,或与事实相反。

比如下面的语句:

  • If I were you, I would go at once.

祈使语气感觉可能有点粗鲁的,因此我们平常不怎么去使用它。但是,对于Git commit的主题行来说,它再适合不过了。而且,Git本身也用祈使语气为我们创建commit. 比如,当我们用git merge 时,它默认给我们创建的commit信息格式如下:

Merge branch 'myfeature'

当用git revert 命令时:

Revert "Add the thing with the stuff"This reverts commit cc87791524aedd593cff5a74532befe7ab69ce9d.

或者当我们点击Github上pull request上的Merge按钮时:

Merge pull request #123 from someuser/somebranch

大家从上面的例子中可以看到,所有的信息都以原形动词开始,因此当你写自己的commit信息时,你应该遵循Git内置的规范,比如下面的例子:

  • Refactor subsystem X for readability
  • Update getting started documentation
  • Remove deprecated methods
  • Release version 1.0.0

起初以这种方式去表达可能会有点尴尬的。我们表达的方式主要是陈述语气,它是关于陈述事实的。这就是为什么commit信息通常出现下面这样方式的原因:

  • Fixed bug with Y
  • Changing behavior of X

有时会把commit信息主题行写成它们内容的描述:

  • More fixes for broken stuff
  • Sweet new API methods

这里我们有一个简单的规则可以使我们的commit信息不再混乱。一个格式良好地commit主题行应该总是会补全下面的句子:

If applied, this commit will your subject line here

比如下面的例子就满足了上面的规则:

  • If applied, this commit will refactor subsystem X for readability
  • If applied, this commit will update getting started documentation
  • If applied, this commit will remove deprecated methods
  • If applied, this commit will release version 1.0.0

而对于非祈使形式的commit信息,就不适用上面的规则:

  • If applied, this commit will fixed bug with Y
  • If applied, this commit will changing behavior of X
  • If applied, this commit will more fixes for broken stuff
  • If applied, this commit will sweet new API methods

注意:仅仅在主题行用祈使语气是重要的,但是当你写commit的正文时,你可以不用遵循这样的规则。

Wrap the body at 72 characters

Git从不会自动地为文本换行。当你写commit信息的正文时,你必须注意它的右间距,手动地对它进行换行。推荐地换行字符数是72个字符,这样Git就会有大量地空间来缩进文本,从而保证整体上每行不会超过80个字符。如果你不想时刻注意着每行的文本数,那么你可以把你的Git提交的默认编辑器改为Vim,你可以安装插件来帮你做这件事情。

Use the body to explain what and why vs. how

下面Bitcoin Core的commit就是一个非常好的例子来解释了what changed and why:

commit eb0b56b19017ab5c16c745e6da39c53126924ed6
Author: Pieter Wuille <pieter.wuille@gmail.com>
Date:   Fri Aug 1 22:57:55 2014 +0200Simplify serialize.h's exception handlingRemove the 'state' and 'exceptmask' from serialize.h's streamimplementations, as well as related methods.As exceptmask always included 'failbit', and setstate was alwayscalled with bits = failbit, all it did was immediately raise anexception. Get rid of those variables, and replace the setstatewith direct exception throwing (which also removes some deadcode).As a result, good() is never reached after a failure (there areonly 2 calls, one of which is in tests), and can just be replacedby !eof().fail(), clear(n) and exceptions() are just never called. Deletethem.

大多数情况下,在你的commit的正文中不需要解释你是怎样做出改变的。因为代码本身会解释这一点,如果代码是非常复杂的,你可以为你的源码加注释来方便日后理解它。因此,我们只需要关注你为什么做出这样地变化,即改变之前事情是怎么工作的,它有什么地主是不对的,现在事情是怎样工作的,为什么你这样做去解决事情的工作方式?

提示

Learn to love the command line. Leave the IDE behind. 要学着去爱上命令行,抛弃IDE.

Git是极其强大的,IDE也是,但是它们强大的地方不同。我每天都会用IDE(IntelliJ IDEA)和其它一些广泛使用的(Eclipse),但是,我从来没见过哪个IDE把Git集成的像它的命令行那样简洁和强大。当然了,在IDE中集成的Git命令是非常棒的,比如当你删除一个文件就像调用git rm,当你重命名一个文件时就像用Git一样可以把事情做对。但是,当你试着去commit,merge,rebase,或者通过IDE去做一些复杂的历史分析时,一切将变得非常困难或者不可行。如果你想要发挥出git的全部力量,你要一直使用命令行。

怎样写好Git的commit信息相关推荐

  1. git修改commit信息

    git修改commit信息 主要有以下3种场景 1.刚刚commit,还没有push,使用git commit --amend. 2.刚刚push,要修改最后一次push的commit信息,使用git ...

  2. 修改git提交commit信息NAME和EMAIL

    (Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu) 参考:https://git-scm.com/docs/git-filter-branch 参考:htt ...

  3. git 只commit不push 会有影响吗_规范化团队 git 提交信息

    规范化团队 git 提交信息 同一个工程项目,为了方便管理,git 的 commit 信息最好按照一定的格式规范,以便在需要的时候方便使用.什么是方便的时候,比如出现了一个线上 bug,所以需要回滚操 ...

  4. 写好 Git Commit 信息的 7 个建议

    介绍: 为什么好的提交信息如此重要 当你随意浏览任一 git 仓库的日志,你很可能会发现其中的提交信息或多或少有点乱.举个例子,瞧一瞧我早先提交到 Spring 上的这些宝贝: $ git log - ...

  5. 规范化git commit信息

    规范化git commit信息 冯宇Ops关注 42019.04.25 19:34:17字数 3,385阅读 1,876 原文链接 前言 在git的使用中,一种最佳实践是使用格式化的commit信息, ...

  6. Git-重写历史知多少(更改 commit 信息)

    经常有以下这些需求: commit 数量比较多,需要合并一些 commit 以保证提交记录清晰 commit 信息写错了 这里还分两种情形,一种是要重写本地仓库的 commit.第二种是已经 push ...

  7. 解决git提交敏感信息(回退git版本库到某一个commit)

    解决git提交敏感信息(回退git版本库到某一个commit) Fri 07 June 2013 git是一个很好的版本库, 现在很多人用它, 并在github上创建项目, 相信大家都有过将敏感信息提 ...

  8. 修改git历史提交的commit信息

    本文是基于idea的操作,亲测可用 前言: 很多公司都会自定义 Git - 使用强制策略,那么他的commit信息就会有固定的格式,一旦不是这个格式,就会出现push失败 但是push失败,很多也只在 ...

  9. git分支合并、撤销;git修改已push的commit信息; git 撤销操作;

    git分支合并 1.分支代码提交 2.git branch 查询本地分支 3.git checkout 分支名1 切换分支到需要合并的分支上 4.git merge 分支名2  //选择要合并到 分支 ...

  10. git 修改远端 commit 信息

    git 修改远端 commit 信息 git rebase -i HEAD~x( x 代表最近几条commit ),执行之后将出现以下界面 上面的 pick 后面即远端的 commit 信息,最下面的 ...

最新文章

  1. 如何进行5万并发用户负载测试?
  2. 怎样用计算机二进制,二进制计算_如何用系统自带的计算器二进制十进制转换...
  3. layuimini tab切换刷新解决方案
  4. 德标螺纹规格对照表_英制螺纹对照表详细介绍,英制螺丝螺纹标准
  5. [经典好文] 谈笑色影间,人生本无忌 (转于色影无忌)
  6. phpcms v9 开发笔记
  7. 电影购票系统软件测试,软件测试(电影售票系统)
  8. 用单片机测量流体流速的_一种测量管道内流体流速的传感器的制作方法
  9. ubuntu 下,用户,文件夹,用户组 之理解
  10. uniapp-连接服务器超时,点击重试
  11. 简单的手机html页面源代码,手机页面h5的简单demo
  12. Chess.com:象棋社区网站每月访问量达 2.8 亿,年收入在 5000 万至 1 亿之间
  13. win10计算机网络设置在哪,Win10系统电脑中的网络状态在哪里查看
  14. githup 提交项目及分支 遇到的问题
  15. python自动化测试学习笔记合集三
  16. 机器学习之十大算法入门
  17. 讲故事的技艺:《极乐迪斯科》中的叙事与机制
  18. uni-app中使用rich-text如何添加样式控制富文本里面的内容
  19. 计算机辅助地理教学的内容,计算机辅助地理教学的优效性的论文
  20. “家贼”倒卖“征途”源代码 13万元卖给识货人

热门文章

  1. ipv6 华为交换机 路由配置_H3C Huawei 交换机 IPv6环境配置
  2. 针对支付宝-当面付实现的个人支付
  3. jenkins k8s 动态增减 jenkins-salve (2) 实现 slave 节点动态构建
  4. linux中swp是什么文件,Linux中.swp 文件的产生与解决方法
  5. ubuntu20 关闭防火墙_ubuntu中如何关闭防火墙
  6. 飞鹅云打印机api接口asp版,asp源码对接飞鹅云小票打印机
  7. 飞一般的感觉——掌智手机助手使用感受
  8. 孩子,外面的世界不会轻易原谅你…
  9. Java并发编程-4-百万流量的短信网关系统
  10. GB/T 20984-2022《信息安全技术 信息安全风险评估方法》解读