HN 写作课

工程师们二十年里聊过的写作。

工程师、作家、编辑和创业者在 Hacker News 上聊了二十年“怎么写”:怎么写得清楚、怎么讲好一个故事、技术文档怎么写、小说和出版是怎么回事。这里把其中关于写作与讲故事的帖子挑出来,配上中文导读、可以直接用的写作要点和评论翻译。

从必读开始
  • 2,600+篇关于写作的 HN 讨论

Writing tips

写作锦囊

正在抽一条写作要点…

Essential

必读 30 篇

在讨论库里看全部精选

编辑精选里 HN 讨论最热的 30 篇,每篇都有中文导读和写作要点。

  1. 正在载入…

Archive

讨论库

按发帖年份分布,点柱子筛选。

排序

    About

    这些讨论是怎么挑出来的

    1. 01

      从全量里捞

      读取 Hacker News 自 2006 年以来的全部帖子,用关键词先捞出 40 分以上、可能和写作有关的约 1.1 万篇。

    2. 02

      只留真正讲写作的

      由 AI 逐条判断是否和写作、讲故事、文风、出版有实质关系,剔除“写代码”“编辑器”这类字面撞车,并分进十个类别。

    3. 03

      提炼可用的要点

      为值得读的帖子写中文导读,提炼 2-4 条可以直接用到自己写作里的要点,并精选翻译 HN 高赞评论。内容由 AI 生成,可能有误。

    技术写作与文档2017chris.beams.io编辑精选

    如何撰写 Git 提交信息

    How to Write a Git Commit Message (2014)

    阅读原文 HN 讨论
    341HN 得分
    118条评论
    4条写作要点

    导读

    这是被广泛引用的 Git 提交信息写作指南:标题与正文空一行、标题限 50 字符、首字母大写、不加句号、用祈使语气、正文每行 72 字符换行、用正文解释「改了什么、为什么改」。它值得写作者读,是因为它把「一句话标题 + 简短说明」的写作训练压缩到了极致:如何在极小的篇幅里说清意图、照顾读者、保持一致的语感,这些原则在邮件、PR 说明、工单、周报里同样适用。

    关键词 Git 提交信息简洁写作祈使语气读者意识

    可以直接用的写作要点

    1. 01

      标题用祈使句开头(Add、Fix、Remove),像给代码库下命令,比「Added」「Fixing」这类叙述更有力也更省字。

    2. 02

      标题控制在 50 字符内、首字母大写、结尾不加句号,把它当新闻标题写,只留读者扫一眼就能抓住的关键信息。

    3. 03

      正文与标题之间空一行,重点说明「改了什么、为什么改」,而「怎么改」交给代码本身去说。

    4. 04

      篇幅要与内容匹配:小改动一句话带过,整体性的改动才值得详细展开,把笔墨花在读者真正需要解释的地方。

    HN 评论精选

    用一份受控的主动动词表开头,让提交信息既能被人快速扫读,又能被工具解析。

    我们团队用一套提交信息规范,既方便快速阅读,也能被工具链解析。我们约定了一份简短的主动动词清单:Add 表示新增能力(功能、测试、依赖);Cut 表示移除能力;Fix 表示修复问题(bug、拼写、误操作、表述错误);Bump 表示提升版本(如依赖);Make 表示改动构建流程、工具或基础设施;Start 表示开始做某事(如创建功能开关);Stop 表示停止做某事;Refactor 表示必须是纯粹重构的改动;Reformat 表示格式层面的重构(如去除空白);Optimize 表示性能层面的重构(如加速代码);Document 表示文档层面的重构(如帮助文件)。

    jph查看英文原文

    My team uses a git commit message convention that helps us read fast and also is parsable by toolchains. We agree on a short list of leading active verbs: Add = Create a capability e.g. feature, test, dependency. Cut = Remove a capability e.g. feature, test, dependency. Fix = Fix an issue e.g. bug, typo, accident, misstatement. Bump = Increase the version of something e.g. dependency. Make = Change the build process, or tooling, or infra. Start = Begin doing something; e.g. create a feature flag. Stop = End doing something; e.g. remove a feature flag. Refactor = A code change that MUST be just a refactoring. Reformat = Refactor of formatting, e.g. omit whitespace. Optimize = Refactor of performance, e.g. speed up code. Document = Refactor of documentation, e.g. help files.

    先想清楚你希望提交历史承担什么功能,写作风格应该从用途倒推,而不是照搬别人的规则。

    这类文章很多,都在强调提交信息的规范性规则,分支与合并的文章也一样,结论却各不相同。在定规则之前更该先讨论:你希望未来给开发者提供哪些工具。把 git 历史当作一等调试工具很强大,但并非必须,而且每种工具都有成本。想要 bisect 可用?那大多数提交就应代表一个完整可用的版本,合并时考虑 squash 分支。想要记录奇怪选择的叙述性文档?细粒度提交适合放这些想法,但可能让开发者不再写行内注释。想要靠 git blame 确定归属?逐行改动有助于找出作者,但也可能让开发者永远无法真正接手代码,在资深开发者少、新人多的创业公司里造成瓶颈。我倾向把 git 历史看作一种上下文工具,像监控、单元测试或文档。值得和团队坐下来明确希望大家能用历史做什么,再据此制定提交风格。

    trjordan查看英文原文

    There are so many articles like this, and all of them focus so much on prescriptive rules for commit messages. There's a similar set of articles on how to deal with branching and merging. Somehow, everybody comes to slightly different conclusions. The discussion that needs to happen before this is to understand what tools you want to make available to your developers in the future. Using git's history as a first class debugging tool is powerful, but it's by no means mandatory to provide. There's also a real cost to providing each of the tools. - Do you want bisect to be available? Well, then you should have most commits represent a fully-functional version of the software. Consider squashing branches when you merge them. - Do you want narrative documentation around strange choices? Fine-grained commits are a great place to put those thoughts, but they may discourage devs from writing those thoughts in inline comments. - Do you want ownership via git blame? Line-by-line changes may help you identify who wrote the code, but that might prevent your developers from ever fully transferring ownership, which could create bottlenecks in startups that have a few long-tenure devs and a lot of recently hired devs. I really like to think of git history as a context tool, like monitoring or unit testing or documentation. It's worthwhile to sit down with your team, define what you want them to be able to do with commit history, and build your commit style from there.

    描述详略要与改动大小匹配,真正该花力气写的是整体改动的说明。

    我的主观印象是:如今提交越来越小。SVN 时代很多人一天只提交几次,甚至几天一次,因为提交要与服务器同步(相当于 git 的 push),所以通常代表代码库的一次较大增量。到了 git,把改动拆成许多很小的提交变得很常见:改变量名?提交。写文档?提交。整体改动并没有变小,只是分散到了更多提交里,所以 SVN 的一次提交在概念上更接近今天的 pull request。这为什么重要?因为用一大段文档去描述「重命名一个局部变量」既费劲又没人受益。我怀念的是对整体改动的良好描述:现在合并提交的描述常常只是自动生成的信息,而这正是我希望人们花时间详细写的地方,所以我喜欢 --squash 合并。我知道改写历史不好,但总的来说,我宁愿读一本历史书,也不愿读 18 世纪的报纸。

    data_hope查看英文原文

    My personal, subjective impression: Commits are getting smaller and smaller nowadays. As in: In the subversion days, many people commited only few times a day, sometimes not for several days. SVN commits of course involved a sync with the server (a "push" in git lingo), and thus usually represented a much larger increment with a substantial change to the code base [X] With git, it became very common to structure changes to a code base in many, very small commits. Rename a variable? Commit. Write some docs? Commit. Of course, the overall changes when developing a feature did not become smaller, they are now just distributed over many more commits. So I'd argue that a SVN commit was often conceptionally closer to what we now have with a git pull-request. Why does this matter? Because It is kind of hard and not helping anyone if you describe your renaming of a local variable with an extensive docstring. What I do miss however, is a good description of the overall change. I.e. now often the description in the merge commit is just the autogenerated message, but this is where I would like people to really take the time and describe the change extensively. This is why I like `--squash` merges, because they let people focus on the relevant parts in their description. I know, rewriting history is bad, but overall, I favour reading a history book than 18th century newspapers. [X] not saying that there weren't small one-line-change commits, but overall they were rarer.

    用 type(scope) 的结构化前缀,让人一眼看出这条信息属于哪类改动。

    我很推荐 Angular 风格的提交信息:type(scope) message,例如 feat(button) added play button。类型包括:feat 新功能;fix 修复 bug;docs 仅文档改动;style 不影响代码含义的改动(空白、格式、缺分号等);refactor 既不修 bug 也不加功能的代码改动;perf 提升性能的改动;test 新增或修正测试;chore 构建流程或辅助工具、库的改动。

    stared查看英文原文

    I really recommend angular-style commit messages: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md type(scope) message e.g. feat(button) added play button Types are: - feat: A new feature - fix: A bug fix - docs: Documentation only changes - style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) - refactor: A code change that neither fixes a bug nor adds a feature - perf: A code change that improves performance - test: Adding missing or correcting existing tests - chore: Changes to the build process or auxiliary tools and libraries such as documentation generation

    同类还值得读

    1. 编写更好文档的框架

      A Framework for Writing Better Documentation

      这是 Divio 的文档写作框架,把技术文档按「读者的目标」分成四类:教程(学习导向)、操作指南(问题导向)、参考(信息导向)、解释(理解导向)。

      技术写作与文档2021 · 637 分 · 76 评4 条写作要点编辑精选
    2. 写好一份设计文档

      Writing a good design document

      这篇 HN 帖子标题为《Writing a good design document》,主题是如何写好一份设计文档;对写作者来说,它值得作为技术写作和结构化说明文的参照。

      技术写作与文档2025 · 581 分 · 147 评3 条写作要点编辑精选
    3. 技术写作课程

      Technical Writing Courses

      这是 Google 官方免费技术写作课程(两门),讲受众定义、主动语态、短句、文档结构等基础方法。

      技术写作与文档2020 · 571 分 · 73 评4 条写作要点编辑精选
    4. 写出更好的错误信息

      Write better error messages

      这篇帖子讨论如何写出更好的错误信息,评论补充了开发者场景下的具体做法和真实反面案例。

      技术写作与文档2022 · 566 分 · 253 评4 条写作要点编辑精选
    5. 写一本技术书的经济账

      The Economics of Writing a Technical Book

      一位技术书作者拆解写书的真实经济账:版税收入往往远低于投入的时间成本。

      技术写作与文档2018 · 519 分 · 149 评4 条写作要点编辑精选

    打赏支持

    打赏二维码

    觉得有用,请作者喝杯咖啡。

    WeChat

    关注向阳乔木

    微信公众号「向阳乔木推荐看」

    微信公众号「向阳乔木推荐看」二维码

    微信扫一扫;在微信里打开本页时,长按二维码识别。