news 2026/10/15 18:15:51

commit-messages-guide:Git 提交信息的价值、最佳实践与历史整理完全指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
commit-messages-guide:Git 提交信息的价值、最佳实践与历史整理完全指南
  • 教程
  • 版本控制

【免费下载链接】commit-messages-guide

A guide to understand the importance of commit messages and how to write them well

项目地址:https://gitcode.com/gh_mirrors/co/commit-messages-guide
点击查看免费下载

导读

本指南源于开源项目 commit-messages-guide,它以韩语完整阐述了"什么是 commit、为什么提交信息重要、如何写出好的提交信息",并附带了交互式变基、精选提交、补丁式暂存等实用 Git 命令的实战示例。读完本文,你将掌握一套可直接落地的提交信息写作规范(祈使语气、首字母大写、50/72 字符限制、正文模板等),理解 Rebase 与 Merge 的历史整理哲学,并学会用rebase -i、cherry-pick、add -p等命令把杂乱的提交历史打磨成干净、可审查、可回溯的记录。文中所有示例均取自该仓库文档原文与仓库自身的配置文件,可放心参照。


一、什么是"commit"?

用最简单的话说,commit(提交)是写入本地仓库的本地文件快照(snapshot)。

很多人误以为 Git 只记录文件的差异(diff),但事实恰恰相反:Git 保存的是所有文件的完整版本。从一个提交到另一个提交之间,如果某些文件没有发生变化,Git 只会为它们创建一个指向之前已存储的相同文件的链接,而不会重复存储内容。这就是 Git 能兼顾"完整版本历史"与"存储效率"的核心机制——每个提交对应一次完整的快照,未变化的文件通过链接复用。

这一节的意义在于:正因为提交是对整个项目状态的快照,而不是零散的补丁,提交信息才需要完整地说明"这次快照做了什么、为什么做",从而为后续的代码审查、问题排查和版本回溯提供上下文。

二、为什么提交信息如此重要?

项目 README_ko-KR.md 明确列出了提交信息带来的四个核心价值:

  • 缩短并简化代码审查(code review)流程:清晰的信息让审查者不必逐行猜测意图;
  • 帮助理解变更:一眼就能看出本次改动的影响范围;
  • 解释"为什么":有些决策无法仅凭代码自解释,"为什么这么做"只能靠文字传达;
  • 帮助后续维护者理解变更的来龙去脉:让问题排查(troubleshooting)与调试(debugging)变得更加容易。

为了最大化这些收益,指南在下一部分给出了一系列可复用的好习惯与标准。

三、写好提交信息的九大最佳实践

说明:这些习惯来自作者的个人经验、网络文章与其他指南的汇总。它是一套帮助性的指导方针(guidelines),而非必须机械遵守的规则——这一点在仓库的 CONTRIBUTING.md 中被反复强调:"Best practices in this guide should aim to help, not to set rule-following blindly standards"。团队或公司可以依据自身约定覆盖其中任意一条,重要的是形成并坚持一套统一的标准。

3.1 使用祈使语气(命令式)

提交信息描述的是变更实际产生的影响、它做了什么,而不是"做了什么(过去时)"。

# 好 使用 InventoryBackendPool 获取库存后端 --- Use InventoryBackendPool to retrieve inventory backend
# 坏 使用 InventoryBackendPool 获取了库存后端 --- Used InventoryBackendPool to retrieve inventory backend

为什么?因为提交信息应该像一条"指令"一样说明变更后系统的行为,而不是回顾历史。英文中祈使句即动词原形开头(Use、Add、Fix),中文则对应"使用、添加、修复"这类不带"了/过"的表述。

3.2 首字母大写

# 好 Add `use` method to Credit model
# 坏 add `use` method to Credit model

理由很简单:遵循英文语法中"句首字母大写"的规则。需要注意的是,这一实践因人、团队、语言而异——韩语版文档的译者特别注明"韩语基本不受此规则影响"。对中文、韩语这类没有大小写区分的语言,这一条自然不适用;但无论是否大写,关键是要确立一个统一标准并持续遵守。

3.3 不查看源码也能读懂变更内容

提交信息应当让读者(审查者、未来的维护者)在不打开源码的情况下就知道变更做了什么。

# 好 给 Credit 模型添加 `use` 方法 --- Add `use` method to Credit model
# 坏 添加 `use` 方法 --- Add `use` method

再对比一组:

# 好 增大文本框与布局框架之间的左侧内边距 --- Increase left padding between textbox and layout frame
# 坏 调整 CSS --- Adjust css

这种"自解释"的提交信息在多种场景下尤其有用:一次提交包含多个变更、涉及重构、或者审查者需要回溯提交者的思考过程。

3.4 用正文(body)解释"为什么、为了什么、怎么做"及更多细节

重点应放在"为什么"而不是"什么"上(虽然"什么"和"怎么做"依然重要)。如果提交信息只是对 diff 的复述,就应该重新思考怎么写。

# 好 修正 InventoryBackend 子类的方法名 继承自 InventoryBackend 的类没有遵守基类接口。 之前之所以能正常工作,是因为 Cart 以错误的方式调用了后端实现。 --- Fix method name of InventoryBackend child classes Classes derived from InventoryBackend were not respecting the base class interface. It worked because the cart was calling the backend implementation incorrectly.
# 好 在 Cart 中将 credits 序列化/反序列化为 json 将 Credit 实例转换为 dict 有两个主要原因: - Pickle 依赖类的文件路径,我们不希望在重构时破坏一切 - dict 与内置类型默认可以被 pickle 序列化 --- Serialize and deserialize credits to json in Cart Convert the Credit instances to dict for two main reasons: - Pickle relies on file path for classes and we do not want to break up everything if a refactor is needed - Dict and built-in types are pickleable by default
# 好 给 Credit 添加 `use` 方法 从 namedtuple 转换为 class,因为我们需要设置一个新的属性(in_use_amount)并赋予新值 --- Add `use` method to Credit Change from namedtuple to class because we need to setup a new attribute (in_use_amount) with a new value

格式要点:

  • 标题(subject)与正文(body)之间用一个空行分隔;后续追加的空行都会被当作正文的一部分;
  • 使用-、*、反引号 ` 等字符可以显著提升可读性,例如用反引号包裹代码标识符(`use` 方法)、用短横线组织要点列表。

3.5 避免无上下文的泛化信息

以下这类"写了等于没写"的提交信息应当坚决避免:

# 坏 修复这个 --- Fix this 修复了一些东西 --- Fix stuff 现在应该能用了 --- It should work now 改了点什么 --- Change stuff 调整 CSS --- Adjust css

这些信息没有说明改的是什么、为什么改,无法支撑代码审查与历史追溯。

3.6 限制每行字符数

指南建议:标题(subject)不超过 50 个字符,正文(body)每行不超过 72 个字符。短标题便于在git log的单行列表、邮件主题、标签页等场景中完整展示;72 字符的行宽则保证在终端与邮件客户端中不折行、便于阅读。

3.7 保持语言一致

  • 项目所有者:选定一种语言,并让所有提交信息都使用该语言;理想情况下,它还应与代码注释、默认翻译语言(针对多语言项目)保持一致;
  • 贡献者:使用提交历史中已经使用的语言来写提交信息,不要自创语言混用。
# 好 ababab Add `use` method to Credit model efefef Use InventoryBackendPool to retrieve inventory backend bebebe Fix method name of InventoryBackend child classes
# 好(韩语示例) ababab Credit 모델에 `use` 메소드 추가 efefef InventoryBackendPool을 사용하여 재고 백엔드를 검색합니다 bebebe InventoryBackend 자식 클래스의 메소드 이름 수정
# 坏(英语与韩语混用) ababab Credit 모델에 `use` 메소드 추가 efefef Use InventoryBackendPool to retrieve inventory backend cdcdcd 이제 잘 작동할거임

3.8 补充实践(源自英文版 README.md)

除上述内容外,英文版文档还补充了两条与韩语版互补的实践,一并列出供参考:

  • 避免使用"this PR / this commit / this patch"这类指代性语言:读者本来就知道这是一次提交,无需自指。This commit does x and y...不如直接写X and y are done...;
  • 避免人称语言(如代词):借鉴学术写作的惯例,避免在提交信息中使用"I"。I fixed the problem.不如改写为The problem has been fixed by doing x and y...。

3.9 提交信息模板

这份模板摘编自 Tim Pope 的提交信息范式,并收录于《Pro Git Book》,是标题 + 正文结构最经典的可复制范本:

在此用不超过 50 个字符概括变更内容 如有必要,在这里写更详细的说明文字,每行大约控制在 72 个字符以内。 在某些上下文中,第一行会被视为提交的标题(subject),其余文字视为 正文(body)。标题与正文之间的空行非常关键(除非你完全省略正文); `log`、`shortlog`、`rebase` 等众多工具都依赖这个空行来区分两部分, 如果把两者连在一起写,这些工具就会被搞糊涂。 解释这个提交要解决的问题。重点说明"为什么"要做这次变更,而不是 "怎么做"(代码本身会解释怎么做)。这次变更是否有副作用,或其他 不符合直觉的影响?这里是说明它们的最佳位置。 后续段落跟在空行之后。 - 要点列表也可以,没问题 - 通常使用短横线(-)或星号(*)作为要点符号,前面加一个空格, 要点之间留空行,但约定可以随时调整 如果你使用问题跟踪器(issue tracker),把引用放在消息底部,像这样: 问题: #123 另见: #456, #789

英文原文如下(与 README_ko-KR.md 中的英文部分一致):

Summarize changes in around 50 characters or less More 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, preceded by a single space, with blank lines in between, but conventions vary here If you use an issue tracker, put references to them at the bottom, like this: Resolves: #123 See also: #456, #789

四、Rebase(变基)与 Merge(合并):两种历史整理哲学

本部分是 Atlassian 教程《Merging vs. Rebasing》的精简版(TL;DR)。

4.1 Rebase(变基)

一句话总结:把工作分支的提交,从基础分支之上一个个地重新拼接,生成一棵新树。

4.2 Merge(合并)

一句话总结:把两个分支的变更合并起来,创建一个新的提交,恰当地称之为"合并提交(merge commit)"。

4.3 为什么有人更偏爱 Rebase 而非 Merge?

作者本人明确表示更偏好 Rebase,理由如下:

  • 生成"干净"的历史,没有多余的合并提交;
  • 所见即所得:在代码审查中,所有变更都来自某个具体的、有明确归属的提交,不会被隐藏在合并提交里;
  • 更多合并由提交者直接处理,每一次合并变更都落在带恰当提交信息的提交中——因为很少有人会去深入审查合并提交,避免合并提交就能确保所有变更都有它该归属的提交。

4.4 什么时候需要 Squash(压缩)?

"Squashing" 是指把一系列提交压缩合并为一个提交。它适用于以下场景:

  • 减少缺乏上下文或过小的提交(例如错别字修正、格式整理、遗漏内容的补充);
  • 把"合并在一起才更有意义"的多个独立变更合成一个;
  • 重写**进行中的工作(work in progress)**提交。

4.5 什么时候应该避免 Rebase 或 Squash?

在公开提交、或多人协作的共享分支上,应避免使用 Rebase 和 Squash。二者都会重写历史并覆盖已有提交;对共享分支(即已推送到远程仓库的提交,或来自其他分支的提交)执行这些操作会造成混乱,并因分叉树与冲突导致他人(本地与远程)的变更丢失。

五、实用的 Git 命令工具箱

5.1rebase -i(交互式变基)

当需要压缩提交、修改消息、重写/删除/调整提交顺序时使用。执行后会打开一个待办清单(todo list),下面这份清单取自指南文档的原始示例(其中的提交信息与该仓库自身的开发历程高度对应):

pick 002a7cc Improve description and update document title pick 897f66d Add contributing section pick e9549cf Add a section of Available languages pick ec003aa Add "What is a commit" section" pick bbe5361 Add source referencing as a point of help wanted pick b71115e Add a section explaining the importance of commit messages pick 669bf2b Add "Good practices" section pick d8340d7 Add capitalization of first letter practice pick 925f42b Add a practice to encourage good descriptions pick be05171 Add a section showing good uses of message body pick d115bb8 Add generic messages and column limit sections pick 1693840 Add a section about language consistency pick 80c5f47 Add commit message template pick 8827962 Fix triple "m" typo pick 9b81c72 Add "Rebase vs Merge" section # Rebase 9e6dc75..9b81c72 onto 9e6dc75 (15 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into the previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out

命令速查表:

命令缩写作用
pickp保留并使用该提交
rewordr使用该提交,但修改其提交信息
edite使用该提交,但停下来允许修改(amend)
squashs使用该提交,但合并进前一个提交
fixupf类似 squash,但丢弃该提交的日志消息
execx用 shell 运行命令行剩余部分
dropd删除该提交

注意注释中的两条警告:删除某一行意味着该提交将永久丢失;如果删除全部内容,rebase 会被中止。

5.1.1 fixup

fixup用于在不需要复杂 rebase的情况下轻松清理提交——把某个小修补贴进前一个提交,同时丢弃它自己的消息,非常适合合并"错别字修正"这类琐碎提交。

5.2cherry-pick(精选提交)

当你把提交误提交到了错误的分支时,无需重写代码,直接把它应用到另一个分支即可。示例:

$ git cherry-pick 790ab21 [master 094d820] Fix English grammar in Contributing Date: Sun Feb 25 23:14:23 2018 -0300 1 file changed, 1 insertion(+), 1 deletion(-)

从输出可以看到,该命令在目标分支上创建了新提交094d820,并保留了原提交的说明信息——这正是它的价值所在:迁移提交的同时迁移语义。

5.3add / checkout / reset --patch(-p补丁式操作)

假设我们面对如下 diff(取自指南文档的原始示例,演示的是在 README 中加入 Template 段落):

diff --git a/README.md b/README.md index 7b45277..6b1993c 100644 --- a/README.md +++ b/README.md @@ -186,10 +186,13 @@ bebebe Corrige nome de método na classe InventoryBackend `` # Bad (mixes English and Portuguese) ababab Usa o InventoryBackendPool para recuperar o backend de estoque -efefef Add `use` method to Credit model cdcdcd Agora vai `` +### Template + +This is a template, [written originally by Tim Pope](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), which appears in the [_Pro Git Book_](https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project). + ## Contributing Any kind of help would be appreciated. Example of topics that you can help me with: @@ -202,3 +205,4 @@ Any kind of help would be appreciated. Example of topics that you can help me wi - [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/) - [Pro Git Book - Commit guidelines](https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project#_commit_guidelines) +- [A Note About Git Commit Messages](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)

使用git add -p可以只暂存我们想要的那部分补丁,而不改动已写好的代码。它非常适合把一次大变更拆成多个小提交,或对特定变更执行 reset / checkout:

Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]? s Split into 2 hunks.

交互提示中y(yes 暂存)、n(no 跳过)、s(split 拆分)、e(edit 手动编辑)是最常用的几个选项。上面的s把一个大 hunk 拆分成了多个小 hunk:

hunk 1
@@ -186,7 +186,6 @@ `` # Bad (mixes English and Portuguese) ababab Usa o InventoryBackendPool para recuperar o backend de estoque -efefef Add `use` method to Credit model cdcdcd Agora vai `` Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]?
hunk 2
@@ -190,6 +189,10 @@ `` cdcdcd Agora vai `` +### Template + +This is a template, [written originally by Tim Pope](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), which appears in the [_Pro Git Book_](https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project). + ## Contributing Any kind of help would be appreciated. Example of topics that you can help me with: Stage this hunk [y,n,q,a,d,/,K,j,J,g,e,?]?
hunk 3
@@ -202,3 +205,4 @@ Any kind of help would be appreciated. Example of topics that you can help me wi - [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/) - [Pro Git Book - Commit guidelines](https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project#_commit_guidelines) +- [A Note About Git Commit Messages](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)

拆分后可以分别决定每个 hunk 的去留,从而把原本混在一起的多处改动拆成几个语义独立的提交——这正是 3.3 节"不查看源码也能读懂变更"能够在实践中落地的手段。同理,git checkout -p与git reset -p可以只对部分变更执行丢弃或撤销操作。

六、仓库自身如何践行这些规范

commit-messages-guide 项目不仅是"纸上谈兵",它的仓库结构与配置就是这套规范的活教材:

  • 多语言协作的工程化组织:README.md 顶部的 "Available languages" 一节列出了包括简体中文(README_zh-CN.md)、繁体中文(README_zh-TW.md)、韩语(README_ko-KR.md)在内的 18 种语言版本,每个版本都以独立文件管理;
  • 贡献规范即最佳实践:CONTRIBUTING.md 明确要求贡献者在提交信息、issue 与 PR 中使用英语,并且"使用指南中描述的最佳实践",还示范了一条合格提交的写法;同时它强调这些实践是帮助性的指导方针而非强制规则,"一个团队的标准可以覆盖通用实践";
  • 代码所有权划分:CODEOWNERS 采用* @RomuloOliveira的默认所有权,并为德语版(README_de-DE.md@Ana06)和乌克兰语版(README_ua-UA.md@CODER591)指定了专项负责人,体现"母语者负责校对"的协作原则;
  • 仓库自身的提交风格:本文写作时仓库的最新提交aa78169 style: capitalize TL;DR in README_de-DE.md就是一条规范示例——祈使语气、首字母大写、50 字符以内的短标题、正文补充说明,完全符合本指南第三部分的标准。

七、补充视野(英文版新增章节速览)

韩语版之外,英文版 README.md 还针对开源协作场景补充了两个密切相关的话题,供需要时查阅:

  • PR 信息与封面信(cover letter):大多数开发者通过 GitHub、GitLab 等平台发起 Pull Request,而内核开发者通过邮件发送补丁时称之为"封面信"。一封好的封面信应总结相关提交系列、交代背景与上下文,帮助维护者理解"为什么这些改动要放在一起";如果是单个或少量提交的小改动,可以把第一个提交当作封面信(GitHub 默认使用第一个提交作为 PR 信息);
  • 签署提交(Sign-off)与项目规范:许多开源项目要求遵守 Developer Certificate of Origin(DCO)等规范——使用真实姓名,并通过git commit -s添加Signed-off-by:行;进一步可使用 GPG(GNU Privacy Guard)对提交进行签名,甚至配合 pinentry 引入 Yubikey、Touch ID 等物理安全层。相关配置命令:
# 仅对当前仓库生效 git config --local user.name "Jane Doe" git config --local user.email "janedoe@janedoe.com" # 或全局生效 git config --global user.name "Jane Doe" git config --global user.email "janedoe@janedoe.com"

结语:从规范到习惯

写好提交信息并非死守教条,而是一套以沟通为目的的工程素养:用祈使语气说清"做了什么",用正文交代"为什么这么做",用 50/72 字符的约束保持可读,用统一语言维护一致性,再用rebase -i、fixup、cherry-pick、add -p把历史整理得干净可信。正如该指南与其 CONTRIBUTING.md 一再强调的——"one size does not fit all",标准可以因团队而异,但统一与坚持本身,就是高质量 Git 历史的第一步。

  • 教程
  • 版本控制

【免费下载链接】commit-messages-guide

A guide to understand the importance of commit messages and how to write them well

项目地址:https://gitcode.com/gh_mirrors/co/commit-messages-guide
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 18:15:34

MiniCode会话管理完全指南:/resume、/fork让AI对话永不丢失

【免费下载链接】MiniCode A lightweight terminal coding assistant with Claude Code-like workflow, tool loop, and TUI architecture, built for learning and experimentation. Multi-language support: TypeScript , Python and Rust implementations available now. 项…

作者头像 李华
网站建设 2026/10/15 18:15:15

SICK LMS111工业激光雷达协议深度解析与UDP配置实战

简介:本资源是面向嵌入式开发与工业自动化方向工程师、高校机器人/智能感知课程学习者的SICK LMS111激光传感器通信开发套件,聚焦解决工业现场设备直连、SOPAS协议解析与实时测距数据获取等核心问题。压缩包共68个文件,含31个头文件&#xff…

作者头像 李华
网站建设 2026/10/15 18:15:07

鱼香ros2(十七)C++小海龟巡逻

一、需求1、需求C服务通信,做个巡逻海龟。让小海龟在海龟模拟器中随机游走进行巡逻。2、分析:1)控制海龟到达目标点我知道,怎么改成动态接收?服务2)用什么接口?自定义的3)随机游走&a…

作者头像 李华
网站建设 2026/10/15 18:15:07

Viper 借助腾讯云函数隐藏 C2 上线 Meterpreter 实战指南

文档教程网络安全 【免费下载链接】Viper Adversary simulation and Red teaming platform with AI 项目地址: https://gitcode.com/gh_mirrors/vip/Viper 点击查看 免费下载 本文介绍如何以腾讯云 API 网关(云函数)为 Viper 的 meterpreter…

作者头像 李华