资讯动态

commit-messages-guide 实战解读:从 Commit 快照原理到编写规范、历史重构与常用 Git 命令

发布时间:2026/10/15 17:21:30 来源:尧图企业网站定制
教程版本控制【免费下载链接】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越南语版 README_vi-VN.md编写系统讲解 Git Commit 的本质、Commit Message 为何重要、编写高质量提交信息的九大最佳实践以及如何通过rebase、squash、cherry-pick和补丁级操作来规划与重构一份清晰的提交历史。读完本文你将掌握一套可直接落地到日常开发与代码评审中的 Commit Message 编写规范并能熟练运用交互式变基等命令管理自己的提交历史。什么是 Commit——快照而非差异很多人误以为 Git 只保存文件版本之间的差异diff实际上并非如此。用最简单的话说一个 Commit 就是你本地仓库中文件的快照snapshot。Git 存储的是所有文件的完整版本而不是文件之间的差异。对于两次提交之间没有发生变化的文件Git 并不会重复保存一份新文件而是保存一个指向先前已存储的相同文件的链接。因此每次提交都是一份完整可恢复的文件状态而不只是改了什么未变更的文件通过链接复用存储不会造成无谓的磁盘浪费每个提交因此都是独立的、可被单独检出的版本节点。下图展示了 Git 随时间推移的存储方式其中每一个Version就是一个 Commit图为原文档引用示意图读者可在原文档中查看Version 1 ──▶ Version 2 ──▶ Version 3 ──▶ Version 4 │ │ │ │ 快照A 快照A(链接) 快照A(链接) 快照A(链接) 快照B 快照B(链接) 快照B(链接) 快照C 快照C(链接) 快照D理解了提交即快照这一底层事实就自然明白每个提交都值得配上一条能说清楚它是什么、为什么存在的消息。为什么 Commit Message 如此重要Commit Message 的价值远不止给提交起个名字它直接关系到协作效率与长期可维护性。原文档总结了四个核心原因加快并简化代码评审code review评审者不需要逐行揣测每个提交的意图一条清晰的消息能让评审过程更快速、更高效帮助他人理解变更消息让团队其他成员在不看 diff 的情况下也能明白这次改动的含义解释为什么很多决策原因无法仅靠代码表达消息是承载这些背景信息的载体帮助未来的维护者多年后维护者可以通过消息弄清为什么改、怎么改的让故障排查troubleshooting与调试debugging变得容易得多。值得注意的是本仓库本身就在践行这一理念仓库的 CONTRIBUTING.md 明确要求贡献者使用英文撰写 commit message、issue 和 PR并且遵循指南中描述的最佳实践。也就是说你正在阅读的这份指南正是用自己倡导的规范写出来的。编写 Commit Message 的九大最佳实践以下实践来自原文档作者的实际经验、互联网文章及其他指南属于建议而非铁律——正如 CONTRIBUTING.md 所强调的Best practices in this guide should aim to help, not to set rule-following blindly standards这些实践是为了帮助你更清晰、更简洁地沟通而不是制造盲从的教条。实践一使用祈使句imperative form提交消息应该描述这次变更实际做了什么、产生了什么效果而不是已经做了什么。# Good Use InventoryBackendPool to retrieve inventory backend# Bad Used InventoryBackendPool to retrieve inventory backend为什么要用祈使句因为一条提交消息是在陈述这次提交带来的行为——让代码去做 X而不是回顾X 已经被做了。这与你给同事下达指令的口吻一致Fix bug、Add feature、Refactor module而非Fixed bug、Added feature。用祈使句写作消息读起来更像一句清晰的指令也更贴近 Git 本身Apply this patch的心智模型。实践二首字母大写# 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 cssAdd \use method没有说明给谁加、加在哪Adjust css更是完全无法传达意图。这种不看代码也能懂的习惯在多提交、多改动、多重构的场景下尤为珍贵——它能让评审者理解提交者当时在想什么也让git log 成为一份可读的变更文档。实践四用正文解释为什么why做什么for what怎么做how及补充细节主题行subject负责一句话概括正文body则承载更深层的背景。原文档给出了三个正面示例# Good 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.# Good 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# Good 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这三个示例都遵循同一结构主题行概括改动 → 空行 → 正文解释动机与取舍。第二个示例甚至以列表形式并列了为什么转成 dict的两个理由第三个示例解释了为什么从 namedtuple 改为 class——这类为什么不选另一个方案的信息是代码本身永远无法表达的。格式上请注意两点主题与正文之间必须用空行分隔空行之后的额外空行都属于正文部分适当使用-、*以及反引号等字符可以让消息更易读例如用反引号包裹代码标识符in_use_amount。实践五避免无上下文、含义笼统的消息以下这类消息对任何读者包括未来的自己都没有信息量# Bad Fix this Fix stuff It should work now Change stuff Adjust css修好了改了下应该能跑了——它们没有说明改了什么、为什么改、问题根因是什么。写消息时不妨问自己如果半年后的我读到这条消息能据此定位问题吗实践六限制字符数Pro Git 的提交规范建议主题行subject不超过 50 个字符正文body每行不超过 72 个字符。限制主题长度能强迫你提炼核心信息限制正文行宽则保证在终端、邮件、评审工具等场景下都能优雅换行显示避免阅读体验被截断破坏。实践七保持语言一致性对项目所有者选定一种语言用它写所有的提交消息理想情况下提交语言应与代码注释、默认翻译语言对本地化项目而言保持一致对贡献者跟随仓库现有提交历史所使用的语言来写。正例——统一使用英文# 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杂糅语言会让检索git log --grep、自动化工具解析和跨团队协作都变得困难。本仓库的做法同样值得借鉴CONTRIBUTING.md 规定仓库内提交、issue、PR 一律使用英文同时为多语言文档维护了 18 个翻译版本见 README.md 的 Available languages 列表其中就包括本文依据的 README_vi-VN.md 与中文版 README_zh-CN.md。实践八使用一份 Commit Message 模板原文档提供的模板最初由 Tim Pope 撰写并收录于《Pro Git》一书。模板原文如下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? Heres 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中文翻译如下越南语版 README_vi-VN.md 还提供了完整的越南语翻译版本便于非英语读者对照理解用 50 个或更少的字符概括变更 如有必要补充更详细的说明文字每行控制在 72 个字符左右。 在某些场景下第一行被视为提交的主题subject其余文本作为 正文body。主题与正文之间的空行至关重要除非你完全省略正文 如果两者连在一起log、shortlog、rebase 等工具可能会被混淆。 解释这个提交要解决的问题。重点说明为什么要做这个改动而不是 怎么做怎么做由代码来说明。这次改动是否有副作用或其他不易 察觉的后果请在这里解释清楚。 后续段落之间用空行分隔。 - 也支持使用列表bullet points - 通常用连字符或星号作为列表标记前面加一个空格条目之间 留空行不过具体约定因项目而异。 如果你使用问题跟踪系统issue tracker请在末尾引用相关编号 Resolves: #123 See also: #456, #789这份模板把主题 正文 空行 列表 issue 引用的完整结构固化下来。你可以在仓库中通过git commit --template或git config commit.template将其配置为默认模板让每次提交都按此结构书写。实践九补充避免this PR / this commit / this patch式指代英文原版 README.md 还补充了两条值得一并采纳的实践。其一不要用这个提交这个 PR这类自我指代——读者当然知道这就是一个提交或 PR没必要重复声明# Bad This commit does x and y... This PR does x and y... This Patch x and y... # Good X and y are done...实践十补充避免人称化表达其二像学术写作一样避免使用人称代词让消息保持客观、聚焦于变更本身# Bad I fixed the problem. # Good The problem has been fixed by doing x and y...Rebase 与 Merge如何构建清晰的提交历史本节是 Atlassian 教程《Merging vs. Rebasing》的精简版TL;DR。越南语版文档特意保留rebase与merge两个英文术语不翻译以免产生歧义——这两个概念在 Git 语境中含义精确建议读者同样直接使用英文关键词检索学习。Rebase 是什么TL;DR把你分支上的提交逐个应用到基础分支之上生成一棵新的提交树。rebase 会将当前分支的每一个提交重放到目标分支的最新状态上得到一条线性的历史。Merge 是什么TL;DR创建一个新的提交——恰当地称之为merge commit合并提交——它承载两个分支之间的全部差异。merge 保留了两条分支各自的演进轨迹用一个额外的合并节点把它们汇合起来。为什么很多人偏好 rebase 而非 merge原文档作者明确表示自己特别偏爱 rebase理由如下产生一条**干净的历史**没有多余的 merge commit所见即所得在代码评审中所有变更都能对应到某个具体、有标题的提交避免改动被藏在合并提交里更多的合并冲突由提交者本人解决且每一次由合并产生的变更都归属于带有恰当消息的提交人们通常不会深入审查 merge commit因此尽量避免它们可以确保所有改动都有一个属于它的提交。什么时候应该 squashSquashing是把一串提交压缩成一个提交的过程。典型适用场景减少几乎没有上下文的提交如修正拼写、格式调整、遗漏的内容把分开的、但合并在一起才更有意义的变更合并为一条提交重写工作进行中work in progress的提交。什么时候应该避免 rebase 或 squash在公共提交public commits或多人共用的共享分支上避免 rebase 和 squash。原因很直接rebase 和 squash 会改写历史、覆盖已有提交。如果对共享分支上的提交例如已经推送到远程仓库的提交或来自其他分支的提交执行这些操作会造成分叉divergent trees与冲突导致协作者丢失他们本地或远程的更改引发混乱。一句话总结历史只在你自己的私有分支上重写一旦提交被推送到公共分支就以 merge 方式演进。实用的 Git 命令理解了理念再看工具。以下是原文档给出的四组高频命令配合真实示例逐一说明。git rebase -i交互式改写历史rebase -i用于 squash 提交、修改消息、重写/删除/重排提交等。执行后会打开编辑器展示如下形式的命令清单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交互式变基中的命令释义命令含义p/pick保留该提交r/reword保留提交但允许修改提交消息e/edit保留提交但停下来供你修改amends/squash保留提交但将其并入上一个提交f/fixup类似 squash但丢弃该提交自己的消息x/exec用 shell 执行该行剩余的命令d/drop移除该提交注意清单中的警告行可以重排命令按从上到下的顺序执行删除一行意味着该提交将永久丢失如果删除全部内容rebase 会被中止。空提交默认会被注释掉。值得一提的细节是上面示例中的提交主题Improve description、Add contributing section、Add Good practices section、Add commit message template、Add Rebase vs Merge section……恰好对应本指南自身各章节的演进过程——这份示例本身就是用规范提交逐步构建文档的真实写照。fixup轻松清理提交fixup用于在不需要复杂 rebase的情况下快速清理提交把它并入前一个提交同时丢弃自身冗余的消息。典型工作流先用git commit --fixupsha创建一条修补提交再通过git rebase -i --autosquash让 Git 自动把 fixup 提交排到目标提交之后并完成合并。对于漏改一处补个空格这类微小修正它比手动 squash 更省心。git cherry-pick把提交搬到正确的分支当你把提交误放到了错误的分支时不必重新编码用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(-)输出清晰地展示了新提交094d820在目标分支master上落地的结果、作者时间与文件变更统计。git add/checkout/reset -p按补丁hunk精细控制-p--patch系列命令允许你只暂存add想要的补丁片段而不改动已写好的代码非常适合把一个大改动拆分成多个逻辑提交或单独 reset/checkout 某处修改。假设我们面对如下 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后Git 会逐个 hunk 询问你的处理方式Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]? s Split into 2 hunks.输入s可将当前 hunk 进一步拆分为更小的 hunk从而精细化控制。上述示例被拆分成了三个 hunkhunk 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)交互提示中的按键含义按?可随时查看完整帮助y暂存该 hunk、n跳过、q退出、a暂存该文件剩余全部 hunk、d跳过该文件剩余全部 hunk、/按正则搜索 hunk、j/J跳到下一个/下一批 hunk、g跳转、s拆分、e手动编辑、?显示帮助。同理git checkout -p与git reset -p允许你对工作区或暂存区做同等级的精细回退操作。延伸阅读与仓库内资料本文主体内容完整继承了 README_vi-VN.md读者可以继续在仓库中查阅README.md英文原版比越南语版多出PR 消息与 cover lettercommit 签名与 DCO避免 this PR/this commit 指代避免人称化等章节是最完整的版本README_zh-CN.md简体中文版适合中文读者对照阅读README_zh-TW.md 及其他 15 个语言的翻译版本完整列表见 README.md 的 Available languages 一节CONTRIBUTING.md仓库贡献指南包含跨语言一致性原则、新翻译检查清单如仅在 README.md 中更新语言列表翻译版本不要包含 Available languages 章节、PR 评审流程至少一位母语者评审、讨论解决后才可合并等实操约定CODEOWNERS代码所有者配置标明各文件的主要维护者LICENSE本仓库采用 Creative Commons Attribution 4.0 InternationalCC BY 4.0许可。本指南的灵感与参考来源包括Chris Beams 的《How to Write a Git Commit Message》、《Pro Git》一书的提交规范章节、Tim Pope 的《A Note About Git Commit Messages》、Atlassian 的《Merging vs. Rebasing》教程、《Pro Git》的 Rewriting History改写历史章节以及 Linux 内核补丁哲学与完美补丁The perfect patch等经典资料均可按名称检索获取。此外whatthecommit.com 与 gitmoji 这类趣味工具也能为提交写作提供灵感。把上面这些实践串起来用祈使句 首字母大写写主题、50/72 字符限制、正文讲清楚为什么、保持语言一致、私有分支上放心用rebase -i与fixup打磨历史、公共分支上以 merge 演进、误提交用cherry-pick补救、大改动用-p精细拆分——你就拥有了一套完整、可落地的提交信息方法论。赞分享教程版本控制【免费下载链接】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点击查看免费下载相关推荐Git Commit Message 撰写实战指南commit-messages-guide 项目的最佳实践与历史整理手册Git Commit Message 撰写实战指南commit messages guide 项目的最佳实践与历史整理手册 commit messages g教程版本控制Armbian 有线网不通Magicsee N5 Max 以太网故障 30 分钟修复指南Armbian 有线网不通Magicsee N5 Max 以太网故障 30 分钟修复指南 闲置的 Magicsee N5 Max 刷完 Armbian想把它嵌入式开发工具构建工具操作系统commit-messages-guideGit 提交信息编写与提交历史整理的完整实战指南commit messages guideGit 提交信息编写与提交历史整理的完整实战指南 本指南以开源仓库 commit messages guide 的葡教程版本控制创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

免费获取报价 →
↑