资讯动态

Git Commit Message 撰写实战指南:commit-messages-guide 项目的最佳实践与历史整理手册

发布时间:2026/10/15 15:25:29 来源:尧图企业网站定制
教程版本控制【免费下载链接】commit-messages-guideA 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 message 的重要性并写出更好的提交信息」为核心的开源指南仓库。本文基于其中的繁体中文版展开系统讲解 commit 的本质、优质提交信息带来的工程收益、九大类撰写最佳实践以及配套的 Rebase、Squash、cherry-pick、交互式暂存等历史整理命令。读完本文你将掌握一套可直接落地的提交信息规范并能用git rebase -i、git add -p等命令规划与重写出一条清晰、可追溯的 commit 历史。什么是 commit简单来说commit 就是在本地数据库中写下的文件快照snapshot。与许多人的直觉相反git 不仅存储不同版本文件之间的差异而是存储所有文件的完整版本对于两个 commit 之间没有被修改的文件git 只额外存储一个指向前一个完全相同文件的链接。这意味着每个 commit 都代表项目在某个时间点的完整状态而不是一串补丁式的增量记录——这也是为什么 commit message 需要承载足够信息的原因它是对这份「完整状态快照」背后意图的注释。英文主文档 README.md 明确指出一个 commit 的价值并不止于代码本身它还承担着向未来维护者传递「为什么与怎么做」的责任这也正是本文后续所有实践标准的前提。为什么 commit 信息很重要一份好的 commit message 能带来四个直接可感知的工程收益加快并简化 code review审查者可以快速从提交信息判断变更意图而不必逐行推导代码。帮助理解一次变更尤其是跨模块、跨文件的重构信息本身就能充当变更的「目录」。解释无法仅靠代码描述的「为什么」业务约束、历史包袱、权衡取舍这些代码读不出来但信息可以写出来。帮助未来的维护人员定位问题明确的「为什么与如何产生变更」能显著降低排查与调试成本。好的实践方式以下实践来自项目作者的经验总结、网络文章与其他指南的整理见 README_zh-TW.md 的「好的实践方式」一节。需要强调的是它们本质上是指南guidelines而非铁律——正如仓库的 CONTRIBUTING.md 所声明的原则实践的目的是帮助团队更好地沟通而不是制造盲目遵守的教条项目、团队或公司的既有约定永远优先于通用惯例。使用祈使句commit message 描述的是这次变更实际上做了什么它的效果而不是「被做了什么」。因此动词应当使用祈使形式# Good Use InventoryBackendPool to retrieve inventory backend # Bad Used InventoryBackendPool to retrieve inventory backend对比两者Use像是在下指令、说明「这次提交将会完成什么」而Used则像是在事后陈述「已经发生了什么」。git 本身也遵循这一惯例——你执行git merge或git revert时git 自动生成的默认提交信息如Merge branch ...、Revert ...都是祈使句。第一个字母大写# Good Add use method to Credit model # Bad add use method to Credit model原因很简单遵守英文句子开头大写的语法规则。当然这条实践可能因人、因团队、甚至因语言而异例如德语的规范名词大写规则就与英语不同——关键不在于是否大写而在于制定一个统一标准并坚持执行。尽量做到只看提交信息就能明白变更而无需查看代码# Good Add use method to Credit model # Bad Add use method # Good Increase left padding between textbox and layout frame # Bad Adjust css对比「为 Credit 模型增加use方法」与笼统的「增加use方法」后者虽然也在陈述动作却没有交代对象与边界「Adjust css」更是完全依赖读者去 diff 里猜改了什么。这条实践在多次 commit、多个变更和重构场景下尤其有价值——它能帮助审查者理解提交者的思考过程也让git log本身变成一份可浏览的变更史。使用信息本身来解释「原因」「目的」「方式」和其他细节信息标题与正文之间用空白行隔开正文中的其他空行会被视为信息内容的一部分。像-、*和反引号这样的符号可以有效提高可读性。以下三个来自原文档的范例展示了正文应该承载什么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.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 defaultAdd use method to Credit Change from namedtuple to class because we need to setup a new attribute (in_use_amount) with a new value注意第一个范例的写法标题交代「改了什么」方法名修正正文交代「为什么之前能用」cart 调用了错误的实现这正是「标题说 what、正文说 why」的经典结构。英文主文档 README.md 还补充了一条判断准则如果 commit message 只是把 diff 复述了一遍就应该重新思考这条信息——重点应放在「为什么」而非「是什么」尽管 what 与 how 仍然重要。避免使用没有上下文的通用信息以下信息几乎无法提供任何检索与审查价值应坚决避免# Bad Fix this Fix stuff It should work now Change stuff Adjust css这类信息的问题在于它们既无法用于git log检索也无法帮助未来维护者判断变更意图属于「有提交、无信息」的典型反例。英文版 README.md 还额外补充了两条相近的禁忌避免使用「this PR」「this commit」「this patch」这类自我指涉的措辞读者本来就知道这是一次提交直接陈述「X and y are done...」即可避免使用「I fixed the problem.」这类人称语言可以借鉴学术写作惯例改用「The problem has been fixed by doing x and y...」的客观表述。限制每行字数参照 Pro Git Book 的 commit 指南建议标题subject最多 50 个字符正文每行最多 72 个字符。这一限制并非强迫症git log、git shortlog、git rebase等工具在渲染提交信息时都会对超长行进行换行或截断超过 72 字符的行在邮件补丁工作流如内核开发中还会引发格式问题。保持行宽可控是让提交信息在各种 git 工具输出中保持可读的前提。保持语言的一致性对项目所有者选择一种语言并用它撰写所有 commit message。理想情况下它应与代码注释、默认翻译地区针对本地化项目等保持一致。对贡献者使用与既有 commit 历史相同的语言撰写。# Good ababab Add use method to Credit model efefef Use InventoryBackendPool to retrieve inventory backend bebebe Fix method name of InventoryBackend child classes# Good (Portuguese example) ababab Adiciona o método use ao model Credit efefef Usa o InventoryBackendPool para recuperar o backend de estoque 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最后一个反面例子中cdcdcd Agora vai葡语「现在会好了」更是同时违反了「无上下文信息」与「语言一致」两条实践。模板下面是原文档给出的参考模板最初由 Tim Pope 撰写并收录于《Pro Git Book》。它演示了上述所有实践如何整合进一份完整提交信息用 50 个左右或更少的字来描述变更 如有必要可以提供更详细的补充说明并尽可能将其限定在每行 72 个字左右。 在某些情况下第一行被视為 commit 的标题其餘的文字被视為内容主体。 因此将标题从内容分离出来的空白行就非常重要(除非完全省略内容)。 如若不然在使用命令列如 logshortlog 以及 rebase 的时候将会很容易混淆。 解释当前 commit 所解决的问题。 请重点描述产生此变更的原因而非方式代码解释了一切。 是否存在副作用以及其他隐含的影响 请在这里将其解释清楚。 接下来请另起一行。 - 也可以使用列舉的格式 (bullet point)。 - 通常使用连字號(-)或星號(*)作為要點段落標記標記與內容之間留一空格各要點之間留一空白行。但這取決於你們的約定。 如果你使用问题追踪器请将對它們的引用放在底部如下所示: Resolves: #123 See also: #456, #789实践上你可以把这段模板保存为 git 的提交模板文件然后通过git config commit.template指向它这样每次执行git commit时编辑器都会自动加载该模板从机制上保证团队成员的提交信息结构统一。Rebase vs. Merge这一部分是对 Atlassian 官方教程「Merging vs. Rebasing」的精华提炼详见 README_zh-TW.md。理解两者的差异是规划干净 commit 历史的前提。RebaseTL;DR将你的分支提交逐个应用于基础分支之上生成一棵新树。执行后原分支上的每个 commit 都会以基础分支的最新状态为父节点重新「铺设」历史呈现为一条直线。MergeTL;DR创建一个新的 commit——称为merge commit合并提交——它记录两个分支之间的差异。Merge 保留了两条分支的原始拓扑因此历史会呈现分叉与汇合结构。为什么一些人更喜欢 rebase 而非 merge项目作者明确表达了对 rebase 的偏好理由包括历史更「干净」没有无用的 merge commit 噪音。所见即所得在 code review 中所有变更都能在某个特定、有标题的 commit 中找到避免修改被藏进 merge commit 里。变更归属清晰merge 通常由提交者执行但实践中很少有人会去深挖和复查 merge commit因此尽量减少 merge commit才能确保每个变更点都有其所属的 commit。什么时候 squash「Squashing」是把一系列 commit 压缩成一个 commit 的过程。以下场景适用减少那些很少甚至没有上下文的 commit拼写错误修正、格式化、遗漏内容的补救将单独发生的变更连接在一起使它们作为一个整体更易理解重写work in progress的 commit开发过程中的临时提交在合并前压成一条有意义的记录。什么时候避免 rebase 或 squash避免在多人共同开发的公共 commit 或共享分支上执行 rebase 和 squash。这两者都会改写历史并覆盖现有 commit一旦作用于已推送到远端仓库的 commit或来自其他分支的 commit就会引发分叉与冲突合作者可能因此丢失本地和远端各自的更改。安全边界很清晰只改写尚未推送到共享远端的本地历史。有用的 git 命令rebase -igit rebase -i交互式 rebase用于压缩提交squash commits、编辑提交信息、重写/删除/重新编排 commit 等。执行后编辑器会打开一个类似下面的待办列表其中每一行对应一个 commit你可以修改每行的动词来改变处理方式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 commits 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值得注意的是上面这份示例待办列表本身就是一个绝佳的实践标本每一行都以祈使句开头Improve、Add、Fix主题控制在 50 字符内正好验证了前文的撰写规范。交互式 rebase 的六种核心动词——pick保留、reword保留但修改信息、edit保留但暂停以补充修改、squash并入前一个提交、fixup并入前一个提交但丢弃其信息、drop删除——覆盖了日常历史整理的全部需求行序可以重排从上到下依次执行。fixupfixup用于轻松清理 commit无需进行复杂的 rebase 流程把一条「修正性」提交并入它要修正的那条提交同时丢弃这条修正提交自己的信息。配合git commit --fixup与git rebase -i --autosquash使用可以自动把修正提交排到正确位置是最低成本的清理手段。cherry-pick当你不小心把 commit 提交到了错误的分支git cherry-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(-)从输出可以看到cherry-pick 在目标分支上创建了一个新 commit094d820并完整保留了原提交的作者信息与变更内容。add/checkout/reset [--patch | -p]git add -p以及git checkout -p、git reset -p允许你按补丁块hunk交互式选择要暂存、检出或重置的变更而无需改动已写好的代码。它在把一个大变更拆分成多个小 commit或只想 reset/checkout 特定部分时非常有用。假设我们有以下 diff注意它展示了原文档历史上一次真实的模板章节新增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后git 会把变更切分为多个 hunk 并逐一询问你的决定交互提示如下Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]? s Split into 2 hunks.输入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新增 Template 章节 -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)交互提示中的选项含义y暂存此 hunk、n跳过、q退出、a暂存本文件后续所有 hunk、d跳过本文件后续所有 hunk、s拆分 hunk、e手动编辑 hunk。这套交互能力与git rebase -i配合足以完成「把一次大改动拆成若干语义清晰的 commit」的完整工作流——而这正是本文所有撰写规范能够落地的操作前提。从撰写到协作PR 消息与提交签署繁体中文版未涉及、但英文主文档 README.md 补充的两块内容与 commit message 撰写直接相关一并说明。PR 消息与 cover letter大多数开发者通过 GitHub、GitLab 等平台以 Pull Request 形式提交代码而通过邮件补丁方式贡献的内核开发者则称之为cover letter。一份好的 PR 消息或 cover letter 应当总结一组相关 commit 的背景与上下文——它相当于这组提交的「说明书」帮助维护者理解「为什么这些变更要一起呈现」从而更好地评估是否合入。对于单条或少数几条 commit 的小型变更可以把第一条 commit 当作 cover letter 使用例如 GitHub 默认以第一条 commit 作为 PR 的默认消息。一份好的 cover letter 通常包含整体变更描述及原因、理解变更所需的背景信息、解决方案与思路的拆解、可能出错的地方caveats、以及超出本次提交范围、留给未来的改进机会。签署提交与遵循指南许多开源项目要求贡献者签署代码并遵循相应指南一个典型例子是Developer Certificate of OriginDCO——Linux 基金会、云原生计算基金会CNCF等组织旗下的项目普遍要求遵守它。这意味着贡献者需要使用真实姓名指能识别你身份的名字不必然是法律姓名并避免使用化名或虚假名称。用git config设置姓名与邮箱# 仅应用于当前仓库 git config --local user.name Jane Doe git config --local user.email janedoejanedoe.com # 或全局生效 git config --global user.name Jane Doe git config --global user.email janedoejanedoe.com提交时加上-s标志git commit -sgit 会自动在提交信息末尾追加一行Signed-off-by:。此外还可以使用GPGGNU Privacy Guard对 commit 进行签名以证明该提交确由你本人创建且在到达他人之前未被篡改如需更强的安全性可配置pinentry结合 Yubikey、Touch ID 等物理设备做二次签名验证。这份指南在仓库自身中的应用本仓库本身就是 commit message 实践最好的落地样本可以从两个层面验证上述规范仓库结构即多语言协作范例仓库根目录下有 README.md英文主文档以及简体中文、繁体中文、日文、韩文等十余个语言版本完整列表见 README.md 的 Available languages 章节这正是「语言一致性」与本地化协作的现实体现。贡献规范明确引用本指南的实践CONTRIBUTING.md 要求贡献者在提交 commit、issue 与 PR 时使用英文并遵循本指南中描述的最佳实践同时列出了优先需要帮助的方向跨语言一致性修正、语法与拼写纠正、引用图片、参考改进、错误或不完整信息的修正、PR 评审、翻译等。其「原则」部分还强调跨语言一致性优先于 100% 正确的语法拼写最佳实践旨在帮助而非制造盲目遵守的规则不同项目、团队或公司的约定可以覆盖通用惯例。延伸阅读原文档在结尾列出了灵感来源与补充阅读详见 README_zh-TW.md 的「灵感、来源以及补充阅读」一节其中值得重点研读的包括关于如何撰写 Git commit message 的经典博文、Pro Git Book 中的 commit 指南章节、关于 Git commit message 撰写的说明文章、Atlassian 的「Merging vs. Rebasing」教程以及 Pro Git Book 的「改写历史」章节。英文主文档 README.md 还额外补充了 Linux 内核补丁哲学与「完美补丁」等进阶材料适合希望深入邮件补丁工作流的读者。结合本文内容你可以立即开始的第一步是把「用 50 个字符以内的祈使句标题 空行 解释 why 的正文」作为自己仓库的提交模板并用git rebase -i与git add -p把已有的一团临时提交整理成清晰、可检索、可追溯的 commit 历史。赞分享教程版本控制【免费下载链接】commit-messages-guideA guide to understand the importance of commit messages and how to write them well项目地址https://gitcode.com/gh_mirrors/co/commit-messages-guide点击查看免费下载相关推荐Armbian 有线网不通Magicsee N5 Max 以太网故障 30 分钟修复指南Armbian 有线网不通Magicsee N5 Max 以太网故障 30 分钟修复指南 闲置的 Magicsee N5 Max 刷完 Armbian想把它嵌入式开发工具构建工具操作系统GlusterFS Git 提交规范实战指南从提交拆分到 Commit Message 撰写的完整实践GlusterFS Git 提交规范实战指南从提交拆分到 Commit Message 撰写的完整实践 导读 本文档是 GlusterFS 项目为开发者制定的存储网络如何编写高效的PR描述commit-messages-guide的Pull Request最佳实践指南 如何编写高效的PR描述commit messages guide的Pull Request最佳实践指南 在开源项目中一个清晰、专业的Pull Requ教程版本控制创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑