changelog-discipline

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

changelog-discipline

changelog-discipline

CHANGELOG — не список изменений, а журнал решений. Список изменений уже есть в истории версий, и он бесполезен через месяц. Ценность даёт то, чего в коде нет: почему сделали именно так, что было до этого, что рассматривали и отвергли.
CHANGELOG并非变更列表,而是决策日志。版本历史中已有变更列表,但这类列表在一个月后便毫无用处。真正有价值的是代码中没有的信息:为何要如此构建、之前的状态是什么、曾考虑过哪些方案又为何否决。

Scope

Scope

  • Применять после любой правки кода в проекте, где ведётся changelog.
  • Применять при настройке changelog в новом проекте.
  • Применять при подготовке релиза.
  • Не применять для сообщений коммитов, описаний PR и релиз-нот для пользователей — другие форматы, другие читатели.
  • 适用于已维护CHANGELOG的项目中,每次代码变更之后。
  • 适用于为新项目配置CHANGELOG时。
  • 适用于准备发布版本时。
  • 请勿用于提交信息、PR描述或面向用户的发布说明——这些是面向不同读者的不同格式。

Core Principles

Core Principles

  • Пишется для того, кто вернётся через полгода. Обычно это сам автор, забывший контекст.
  • «Почему» дороже «что». Что изменилось — видно в диффе. Почему выбрали этот вариант — не видно нигде.
  • Отвергнутая альтернатива ценнее описания принятой. Она не даст через полгода переделать обратно и наступить на те же грабли.
  • Запись делается сразу, а не перед релизом. Через неделю причина решения забыта, останется пересказ диффа.
  • Незаписанное изменение = потерянное решение. Правило работает только как безусловное; «в этот раз мелочь» ломает его целиком.
  • **为半年后回头看的人而写。**通常这个人就是已经遗忘上下文的原作者。
  • **「为何」比「是什么」更重要。**变更了什么在代码差异中一目了然,但为何选择此方案却无从知晓。
  • **被否决的替代方案比已采纳方案的描述更有价值。**它能避免半年后有人走回头路,重蹈覆辙。
  • **记录需即时完成,而非等到发布前。**一周后决策的原因就会被遗忘,最后只剩对代码差异的复述。
  • **未记录的变更=丢失的决策。**这条规则必须无条件执行;「这次只是小改动」的想法会彻底破坏它的有效性。

Формат

格式

Структура файла

文件结构

markdown
undefined
markdown
undefined

Changelog

Changelog

Все заметные изменения <проект>. Формат — Keep a Changelog.

Все заметные изменения <проект>. Формат — Keep a Changelog.

[Unreleased]

[Unreleased]

Added

Added

Changed

Changed

Fixed

Fixed



[0.1.3] — 2026-07-31

[0.1.3] — 2026-07-31

<Заголовок релиза — одной фразой о сути>

<Заголовок релиза — одной фразой о сути>

  • Что:
  • Где:
  • Почему:
  • Было:
  • Что:
  • Где:
  • Почему:
  • Было:

Added

Added

Changed

Changed

Fixed

Fixed

undefined
undefined

Резюме релиза — четыре поля

版本发布摘要——四个字段

Самая ценная часть. Не пересказ пунктов ниже, а ответ на вопрос «что вообще поменялось в продукте»:
ПолеЧто отвечает
Чточто теперь работает иначе, в терминах продукта, а не кода
Гдекакие файлы и области затронуты — точка входа для того, кто полезет разбираться
Почемукакую боль это снимает; ради чего вообще делалось
Былокак вело себя до — иначе через полгода непонятно, что чинили
Поле Было чаще всего пропускают, и зря: без него запись описывает мир, которого читатель не помнит.
这是最有价值的部分。不要复述下方的条目,而是回答「产品整体发生了哪些变化」这一问题:
字段说明
是什么站在产品而非代码的角度,说明现在哪些功能的运作方式发生了改变
在哪里涉及哪些文件和区域——为需要深入研究的人提供切入点
为何解决了什么痛点;做这项变更的初衷是什么
之前状态变更前的运作方式——否则半年后没人明白当初修复的是什么问题
之前状态字段常被忽略,但这是错误的:没有它,记录描述的是读者早已遗忘的过往状态。

Пункты внутри секций

各章节内的条目

Одна запись = одно решение, а не один коммит. Внутри записи:
  • жирный заголовок — суть одной фразой
  • что именно поменялось, с упоминанием затронутых типов и функций
  • почему выбрали так, если решение неочевидно
  • что отвергли и почему, если рассматривались варианты
Пример:
ПКМ вместо всплывающего меню по ховеру. Копирование ссылки из текста переехало в контекстное меню (
LinkContextMenu
). Сначала это было всплывающее по ховеру микро-меню, но до кнопки не успевал доехать курсор — контекстное меню совпадает с поведением родного текстового поля и не требует ни за чем успевать.
Здесь есть отвергнутый вариант и причина отказа. Через полгода это не даст «улучшить» обратно.
一条记录对应一项决策,而非一次提交。记录内容应包含:
  • 加粗标题——用一句话概括核心内容
  • 具体变更内容,提及涉及的类型和功能
  • 为何选择此方案(若决策并非显而易见)
  • 曾否决哪些方案及原因(若曾考虑过其他选项)
示例:
右键菜单替代悬浮弹出菜单。文本中的链接复制功能移至右键菜单(
LinkContextMenu
)。最初采用的是悬浮弹出式微型菜单,但鼠标光标往往来不及移到按钮上——右键菜单与原生文本框的行为一致,无需赶时间操作。
这段记录包含了被否决的方案及原因。半年后,这能避免有人将其「改回原样」。

Workflow

Workflow

  1. После правки кода — сразу дописать в
    [Unreleased]
    , в подходящую секцию (Added / Changed / Fixed).
  2. Формулировать от продукта, а не от кода: не «добавил параметр в функцию», а «теперь можно X».
  3. Если решение неочевидно — добавить, почему выбрано так и что отвергнуто.
  4. При релизе — превратить
    [Unreleased]
    в версию с датой и написать резюме из четырёх полей.
  1. 代码变更后——立即在
    [Unreleased]
    章节下的对应板块(Added / Changed / Fixed)中补充记录。
  2. 站在产品角度描述,而非代码角度:不说「为函数添加了参数」,而说「现在可以实现X功能」。
  3. 若决策并非显而易见——补充说明为何选择此方案以及曾否决哪些选项。
  4. 发布版本时——将
    [Unreleased]
    转换为带日期的版本,并撰写包含四个字段的发布摘要。

Проверка качества

质量检查

Запись хорошая, если через полгода по ней можно ответить:
  • что изменилось для пользователя;
  • почему сделали так, а не иначе;
  • где смотреть код;
  • как было раньше.
Если запись пересказывает дифф — она бесполезна, дифф и так есть.
一份优质的记录应能在半年后回答以下问题:
  • 用户层面发生了哪些变化;
  • 为何选择此方案而非其他;
  • 代码查看位置;
  • 之前的状态是什么。
如果记录只是复述代码差异,那它毫无用处——代码差异本身就存在。

References

References

  • references/01-antipatterns.md
    — как не надо, с разбором
  • references/02-examples.md
    — примеры записей до и после
  • references/01-antipatterns.md
    — как не надо, с разбором
  • references/02-examples.md
    — примеры записей до и после