commit-messages-guide:Git 提交信息编写与提交历史整理的完整实战指南
教程版本控制【免费下载链接】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_pt-BR.md为骨架展开系统讲解 commit 的本质快照而非差异存储、提交信息为何重要、十余项被广泛验证的编写最佳实践以及通过rebase、squash、cherry-pick、交互式暂存等命令规划与重写提交历史的方法。读完本文你将能够写出结构规范、语义清晰、便于代码审查与回溯的高质量提交信息同时掌握何时以及如何安全地整理提交历史。仓库背景一份多语言维护的提交信息指南commit-messages-guide 是一个纯文档仓库不含任何源代码或可执行程序其内容全部由一组 Markdown 文件构成英文主文档 README.md、包括葡萄牙语 README_pt-BR.md 在内的 18 种语言版本、贡献规范 CONTRIBUTING.md、代码所有者清单 CODEOWNERS 与 LICENSE。需要特别说明的一点是葡萄牙语版本虽然早于英文版编写但正如文档自身在开篇注释README_pt-BR.md中所述英文版包含一些更详尽的文本与更完善的引用。因此本文在严格继承葡萄牙语版本完整内容的基础上会适度引入英文主文档README.md中属于同一主题的补充章节如 PR 消息撰写、提交签名等以呈现一个信息更完整的知识体系。什么是 commit用最简单的话说commit 是你本地文件的一份快照snapshot被写入本地仓库。这与很多人的直觉相反Git 存储的并不只是文件之间的差异而是所有文件的完整版本只有当某个文件在两个 commit 之间没有发生变化时Git 才会只存储一个指向上一次快照中相同文件的引用从而避免重复占用空间。这个快照模型对提交信息的写作有直接启示既然每个 commit 都是项目在某一时刻的完整记录那么提交历史就是项目演进过程的唯一可信档案而每一行提交信息就是这份档案的标题与摘要。历史能否被后人高效阅读完全取决于这些标题写得好不好。为什么提交信息很重要README_pt-BR.md 在Por que as mensagens são importantes?为什么提交信息重要一节中给出了四条核心理由加快并简化代码审查code review审查者无需逐行猜测改动意图读信息即可快速把握变更方向帮助理解发生了什么一条清晰的提交信息本身就是变更的说明文档解释代码无法表达的隐藏原因很多决策权衡、约束、历史包袱只存在于提交者的脑子里只能靠文字传达方便故障排查与调试让未来的维护者搞清楚为什么改以及怎么改的从而更快定位问题。要最大化这些收益就需要一套被反复验证的编写规范这正是本指南的核心价值所在。编写提交信息的最佳实践以下实践综合自作者经验、互联网文章与其他指南逐条展开。1. 使用祈使句Imperative# Good Use InventoryBackendPool to retrieve inventory backend# Bad Used InventoryBackendPool to retrieve inventory backend为什么必须用祈使句因为提交信息描述的是该变更将要做什么does而不是已经做了什么was done。祈使句让信息读起来像一条对仓库下达的指令与 Git 内部生成的Merge branch ...、Revert ...等自带提交的措辞风格天然一致。2. 首字母大写# Good Add use method to Credit model# Bad add use method to Credit model文档特别指出这是一条颇具争议、且作者本人认为重要性最低的规则——选择大写首字母的唯一理由只是遵循句子开头大写的通用语法习惯。是否大写因人、因团队、因语言而异真正的关键是选定一个标准并始终如一地执行。3. 让信息自解释无需查看源码提交信息应当独立传递完整语义读者不打开 diff 就能明白改动内容# Good Add use method to Credit model# Bad Add use method# Good Increase left padding between textbox and layout frame# Bad Adjust css在多次提交、多项变更与大规模重构的场景下例如Add use method这类信息出现在一连串提交中时清晰的信息能帮助审查者理解提交者当时的思考脉络。4. 用正文解释为什么为了什么怎么做及额外细节信息主题subject与正文body之间用一个空行分隔额外的空行会被视为正文的一部分。正文应当聚焦于为什么而非是什么——如果提交信息只是把 diff 复述一遍就值得重新思考写法。-、*、反引号等字符是提升正文可读性的常见手段。三个完整的正面示例# Good Fix method name of InventoryBackend child classes Classes derived from InventoryBackend were not respecting the base class interface. It worked because 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 picklable 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注意观察这三个例子的共性主题一句话概括做了什么正文紧接着解释为什么这样做——要么是修复了某个接口约束被破坏的问题要么是出于序列化稳定性与重构安全性的权衡要么是为了新增属性而更换数据结构。这种主题理由的结构正是正文存在的意义。5. 避免无上下文、过于笼统的信息以下都是应当避免的反面典型# Bad Fix this Fix stuff Agora vai Change stuff Adjust css这类信息对审查者和未来维护者毫无帮助——它们既没有说明问题也没有说明方案。6.补充避免 this PR / this commit / this patch 之类的自我指涉措辞英文主文档README.md补充了一条重要规则不需要在信息里指代提交本身——读者当然知道这是一条提交、补丁或 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...7.补充避免个人化语言如人称代词从学术写作中可以借鉴的一条经验是提交信息应当避免使用个人化语言保持客观中性# Bad I fixed the problem. # Good The problem has been fixed by doing x and y...8. 控制字符长度据《Pro Git Book》中的提交规范建议主题行控制在 50 个字符以内正文每行约 72 个字符。50/72 这两个数字是为了让信息在git log、git shortlog等终端工具中保持整齐的排版也强制提交者把信息写得精炼。9. 保持语言的一致性语言一致性需要从两个视角分别落实项目所有者视角选定一种语言用它撰写所有提交信息。理想情况下该语言应与代码注释、本地化项目的默认翻译语言等保持一致贡献者视角使用与现有提交历史相同的语言来撰写自己的提交信息。# Good ababab Add use method to Credit model efefef Use InventoryBackendPool to retrieve inventory backend bebebe Fix method name of InventoryBackend child classes# Good葡萄牙语示例 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混用英语与葡萄牙语 ababab Usa o InventoryBackendPool para recuperar o backend de estoque efefef Add use method to Credit model cdcdcd Agora vai10. 使用标准模板README_pt-BR.md 的Exemplo de formato一节给出了一个直接可用的完整模板。该模板最初由 Tim Pope 编写并收录于《Pro Git Book》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模板的要点可以归纳为四层第一行主题 ≤50 字符空行之后是为什么的说明聚焦原因而非手段并交代副作用再之后是补充段落与项目符号列表最后在底部附上问题跟踪器引用Resolves: #123、See also: #456, #789。规划与重写提交历史Rebase 与 Merge 的选择编写好单条提交信息之后下一个层面是规划整段历史。文档这一节是对 Atlassian 的《Merging vs. Rebasing》教程的 TL;DR 浓缩。Rebase把分支提交逐个搬到目标分支之上TL;DR将你分支上的提交逐个应用到基础分支之上生成一棵新的树。结果是提交历史呈现一条干净的直线没有多余的合并节点。Merge用合并提交把两棵树缝合TL;DR创建一个新的提交即 merge commit合并提交其中包含你所在分支与基础分支之间的差异。合并会保留双方各自的历史脉络代价是在历史中留下合并节点。为什么有人偏爱 rebase文档作者明确表示个人更倾向于 rebase理由包括历史更干净没有散布在历史中、无意义的 merge commit所见即所得WYSIWYG在 code review 时你看到的是 master 与分支之间真实的 diff所有改动都能定位到某个具体且有名有姓的提交而不是被藏在 merge commit 里复杂冲突由提交者解决并归属到一条带正当消息的提交内没有人会去深挖并审查 merge commit 的内部这正是 merge commit 的危险所在——避免它们才能确保每处改动都落在它应有的提交里。何时该 squashSquash 是把一串提交压缩合并成一个提交的过程。在以下几种场景中尤其适用历史中存在大量缺乏上下文的补充性提交拼写修正、格式调整、遗漏的内容分散在多个提交中、但合在一起才更有意义的改动需要重写的 WIPwork in progress草稿提交。何时应避免 rebase 或 squash在公共提交、或多人共同工作的共享分支上应避免 rebase 与 squash。二者的本质都是重写历史、覆盖既有提交。如果对共享分支上的提交即已推送到远程仓库、或来自其他分支的提交执行这类操作会造成分支树分叉与冲突导致协作者丢失本地或远程的更改引发混乱。实用 Git 命令整理提交历史的工具箱git rebase -i交互式变基用于压缩提交squash、编辑消息、重写/删除/重排提交等。文档给出的完整示例非常有趣其中的每个pick行正是本仓库自身历史上真实提交信息——它们本身就是信息自解释的最佳实例Improve description and update document title、Add contributing section、Add Rebase vs Merge section……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 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在交互式编辑器中最常用的几个指令含义如下指令缩写作用pickp保留该提交rewordr保留提交但编辑其提交信息edite保留提交但停下来允许git commit --amend修改squashs将该提交并入前一个提交消息会合并fixupf同squash但丢弃本提交的日志消息execx用 shell 执行命令行剩余部分dropd删除该提交同时要牢记编辑器里的三条警告行可以重排并按从上到下的顺序执行删除某一行意味着该提交将永久丢失如果删光所有行则整个 rebase 会被中止。fixup轻量级清理fixup的价值在于可以轻松清理提交而无需进行一次复杂的 rebase。它的典型用法是配合git commit --fixupcommit创建一条补丁提交再通过git rebase -i --autosquash自动把补丁并入目标提交并丢弃多余消息——适合处理拼写修正、格式调整这类不值得单独留痕的小改动。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(-)git add/checkout/reset --patch-p按 hunk 精细控制假设我们手头有一个如下 diff文档以 README.md 的一次真实修改为例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时非常有用。当选择s拆分时交互界面如下Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]? s Split into 2 hunks.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)交互提示中的字母含义y暂存当前 hunk、n跳过、q退出、a暂存本文件所有剩余 hunk、d跳过本文件剩余 hunk、s进一步拆分当前 hunk、e手动编辑 hunk。同样的-p模式也适用于git checkout -p放弃部分改动与git reset -p从暂存区部分撤出三者共同构成对 diff 的精细控制能力。进阶主题面向开源协作的提交规范英文主文档README.md中还有两个与提交信息密切相关的进阶主题这里一并补充。PR 消息与 cover letter 的撰写大多数开发者在 GitHub、GitLab 等平台上以 Pull Request 形式提交变更而内核开发者等通过邮件发送补丁的人群则称之为 cover letter封面信。无论哪种形式一封好的 PR 消息 / cover letter 应当为一组相关提交提供概括、背景与上下文帮助维护者理解为什么这些改动要放在一起呈现从而更有效地推销你的提交序列。对于小规模改动单个或少量提交可以直接把第一个提交当作 cover letter——例如 GitHub 默认就用第一个提交作为 PR 消息。一封高质量 cover letter 通常包含整体改动及其动机的描述、理解这些改动所需的背景信息、解决方案与实现思路的拆解、可能出问题的注意事项caveats、以及超出当前提交集范围的未来增强方向。Signed-off-by 与 DCO 提交签名许多开源项目要求贡献者签署代码并遵循相应规范典型代表是Developer Certificate of OriginDCO开发者来源证书——Linux 基金会、云原生计算基金会CNCF等组织的项目普遍要求遵守。这意味着你需要使用真实姓名即能标识你本人的名字不一定是法定姓名但应避免假名并在提交上签名# 仅对当前仓库生效 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 会自动在提交信息中追加一行Signed-off-by: ...git commit -s除了 DCO 签名行还可以使用GPGGNU Privacy Guard对提交做加密签名向他人证明这个提交确实由你创建、且在到达他人之前未被篡改。Git 通过user.signingkey与commit.gpgsign配置配合 GPG 密钥使用更进一步可以借助pinentry等工具接入 YubiKey、Touch ID 等硬件层面的物理安全层。如何在仓库中继续深入通读英文权威版本 README.md其中包含葡萄牙语版缺失的更详尽章节如自我指涉措辞、个人化语言、PR 消息、签名规范阅读简体中文版 README_zh-CN.md 与繁体中文版 README_zh-TW.md对照不同语言版本之间的信息一致性查看 CONTRIBUTING.md 了解贡献规范——值得注意的是该文档本身要求提交信息、issue 与 PR 使用英文并遵循本指南的最佳实践堪称用指南指导自身仓库的闭环示例通过 CODEOWNERS 了解各语言版本的维护者归属通过 LICENSE 确认许可条款。此外文档还推荐了两个趣味延伸whatthecommit.com随机生成无意义提交信息的娱乐站点反向印证好信息的重要性与 gitmoji用 emoji 标注提交类型的社区约定。其正文引用的主要思想来源包括 Chris Beams 的《How to Write a Git Commit Message》、Tim Pope 的《A Note About Git Commit Messages》、《Pro Git Book》中的提交规范与改写历史章节以及 Atlassian 的《Merging vs. Rebasing》教程。结语从commit 是快照这个底层模型出发到祈使句、首字母大写、正文写为什么、50/72 字符限制、语言一致性、标准模板这一整套可落地的编写规范再到 rebase、squash、cherry-pick、交互式暂存与签名机制这一系列历史整理工具commit-messages-guide 用一份文档串联起了提交信息写作的完整链路。它的核心理念值得反复强调提交信息是给未来的维护者包括未来的自己写的它描述的应当是变更的意图与原因而不只是变更本身。把这套实践内化为习惯你的提交历史就会从流水账变成一份高质量的项目演进档案。赞分享教程版本控制【免费下载链接】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 messages guide编写优质提交信息的指南 在现代软件开发实践中提交信息commit messages是版本控制的重要部分。今天教程版本控制electerm终端主题与字体优化5个提升工作效率的实用技巧electerm终端主题与字体优化5个提升工作效率的实用技巧 你是否在使用electerm终端时感到眼睛疲劳是否觉得默认界面不够个性化作为一款功能强大的跨桌面应用开发工具网络终极指南30分钟本地部署Duix-Avatar打造你的专属AI数字人终极指南30分钟本地部署Duix Avatar打造你的专属AI数字人 想要拥有一个能够完美复刻你形象和声音的数字分身吗Duix Avatar正是你寻找的答案人工智能AI 应用数字人媒体生成桌面应用创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考