---
title: Ведите changelog
description: Не позволяйте своим друзьям сливать логи Git в changelog’и.
language: ru
version: 1.0.0
---
.header
.title
%h1= current_page.data.title
%h2= current_page.data.description
= link_to data.links.changelog do
Version
%strong= current_page.metadata[:page][:version]
%pre.changelog{ lang: "en" }= File.read("CHANGELOG.md")
.answers
%h3#what
%a.anchor{ href: "#what", aria_hidden: "true" }
Что такое лог изменений?
%p
Лог изменений — это файл, который содержит поддерживаемый, хронологически
упорядоченный список значимых изменений для каждой версии проекта.
%h3#why
%a.anchor{ href: "#why", aria_hidden: "true" }
Зачем вести лог изменений?
%p
Чтобы пользователям и контрибуторам было проще в точности понять,
какие значимые изменения были внесены в каждый выпуск (или версию)
проекта.
%h3#who
%a.anchor{ href: "#who", aria_hidden: "true" }
Кому нужен лог изменений?
%p
Людям. Конечные пользователи программного обеспечения, будь то клиенты или разработчики, —
это человеческие существа, которым небезразлично, с чем они работают. Когда
программное обеспечение изменяется, люди хотят знать, что и почему изменилось.
.good-practices
%h3#how
%a.anchor{ href: "#how", aria_hidden: "true" }
Как мне сделать хороший лог изменений?
%h4#principles
%a.anchor{ href: "#principles", aria_hidden: "true" }
Руководящие принципы
%ul
%li
Лог изменений — для людей, а не для машин.
%li
Для каждой версии без исключения следует создать отдельный раздел.
%li
Однотипные изменения следует группировать.
%li
Следует предусмотреть возможность поставить ссылку на любую версию или раздел.
%li
Последняя версия должна идти в начале файла.
%li
Указаны даты выпуска каждой версии.
%li
Уточните, следуете ли вы принципам #{link_to "семантического версионирования", data.links.semver}.
%a.anchor{ href: "#types", aria_hidden: "true" }
%h4#types Типы изменений
%ul
%li
%code Добавлено
— для новых функций.
%li
%code Изменено
— для изменений в существующей функциональности.
%li
%code Устарело
— для функций, которые скоро будут удалены.
%li
%code Удалено
— для удалённых на данный момент функций.
%li
%code Исправлено
— для любых исправлений багов.
%li
%code Безопасность
— на случай уязвимостей.
.effort
%h3#effort
%a.anchor{ href: "#effort", aria_hidden: "true" }
Как мне тратить меньше усилий на ведение лога изменений?
%p
Держите в начале файла раздел Новое
, позволяющий отслеживать
предстоящие изменения.
%p Это служит достижению двух целей:
%ul
%li
люди смогут видеть, каких изменений им можно ожидать в предстоящих выпусках;
%li
в момент релиза вы можете переместить изменения из раздела Новое
в раздел нового выпуска.
.bad-practices
%h3#bad-practices
%a.anchor{ href: "#bad-practices", aria_hidden: "true" }
Бывают ли плохие логи изменений?
%p Да. Вот несколько причин, по которым они могут оказаться совершенно бесполезными.
%h4#log-diffs
%a.anchor{ href: "#log-diffs", aria_hidden: "true" }
Diff’ы лога коммитов
%p
Использование diff’ов лога коммитов в качестве лога изменений — это плохая идея:
они полны информационного шума от слияния коммитов, от коммитов с непонятными
заглавиями, от изменений, вносимых в документацию, и т. п.
%p
Назначение коммита в том, чтобы задокументировать шаг в эволюции исходного
кода. В некоторых проектах следят за историей коммитов, в некоторых — нет.
%p
Назначение же раздела в логе изменений — задокументировать заслуживающие
внимания различия (зачастую привнесённые несколькими коммитами), чтобы внятно
сообщить конечным пользователям об этих различиях.
%h4#ignoring-deprecations
%a.anchor{ href: "#ignoring-deprecations", aria_hidden: "true" }
Игнорирование устаревших функций
%p
Когда люди переходят с одной версии продукта на другую, им должно быть до боли
ясно, в какой именно момент что-то сломается. Следует предусмотреть возможность
перейти к версии, в которой перечислены устаревшие функции, удалить то,
что устарело, а затем перейти к версии, из которой эти устаревшие функции
удалены.
%p
Перечисляйте в логе изменений устаревшие и удалённые функции, а также любые
критические изменения, даже если не перечисляете ничего другого.
%h4#confusing-dates
%a.anchor{ href: "#confusing-dates", aria_hidden: "true" }
Даты, сбивающие с толку
%p
Региональные форматы дат различаются по всему миру, и зачастую трудно найти
удобный для человека формат, который был бы интуитивно понятен каждому.
Преимущество дат в форматах наподобие 2017-07-17
заключается
в том, что элементы в них следуют в порядке от более крупной единицы измерения
к более мелкой: год, месяц и день. К тому же, в отличие от некоторых
региональных форматов, в которых изменено положение чисел, обозначающих день
и месяц, этот формат не пересекается с другим и не вызывает неоднозначных
толкований. Исходя из этих причин и того факта, что этот формат соответствует
#{link_to "стандарту ISO", data.links.isodate}, именно он рекомендован для записей в логе
изменений.
%aside
Есть кое-что ещё. Помогите мне собрать эти антипаттерны,
подав #{link_to "заявку о наличии проблемы", data.links.issue}
или pull request.
.frequently-asked-questions
%h3#frequently-asked-questions
%a.anchor{ href: "#frequently-asked-questions", aria_hidden: "true" }
Часто задаваемые вопросы
%h4#standard
%a.anchor{ href: "#standard", aria_hidden: "true" }
Существует ли стандартный формат для логов изменений?
%p
На самом деле, нет. Есть #{link_to "стилистический путеводитель по логам изменений от GNU", data.links.gnustyle},
есть #{link_to "«руководство» длиной в два абзаца по файлам GNU NEWS", data.links.gnunews}.
Оба или неадекватны, или недостаточно полны.
%p
Этот проект нацелен на то, чтобы стать
#{link_to "улучшенной версией соглашения о формате логов изменений", data.links.changelog}.
Проект опирается на отслеживание и накопление передового опыта сообщества
пользователей открытого исходного кода.
%p
Здоровая критика, дискуссии и предложения по улучшению
#{link_to "приветствуются", data.links.issue}.
%h4#filename
%a.anchor{ href: "#filename", aria_hidden: "true" }
Как назвать файл лога изменений?
%p
Назовите его CHANGELOG.md
. Некоторые проекты используют
HISTORY
, NEWS
или RELEASES
.
%p
Хотя легко подумать, что имя файла лога изменений не имеет большого значения,
зачем усложнять вашим конечным пользователям поиск места,
в котором описаны все значимые изменения?
%h4#github-releases
%a.anchor{ href: "#github-releases", aria_hidden: "true" }
Что насчёт функции «Релизы» на GitHub’е?
%p
Это отличная инициатива. #{link_to "Релизы", data.links.github_releases} можно использовать
для превращения простых тегов Git (например, тега, названного v1.0.0
)
в подробные примечания к выпускам, вручную добавляя эти примечания, или же
можно извлечь сообщения из аннотированных тегов Git и превратить их в примечания.
%p
Релизы на GitHub’е создают непортируемый лог изменений, который может быть
показан пользователям только на самом GitHub’е. Имеется возможность вести такой лог
в формате, очень похожем на формат проекта Keep a Changelog, но это, как правило,
требует большей вовлечённости в процесс.
%p
Также возможно, что конечным пользователям не всегда легко обнаружить
текущую версию GitHub Releases, в отличие от обычных файлов с именами в верхнем
регистре (README
, CONTRIBUTING
и т. д.).
Другая небольшая проблема заключается в том, что в настоящее время
интерфейс не предлагает ссылок на логи коммитов, выполненных между релизами.
%h4#automatic
%a.anchor{ href: "#automatic", aria_hidden: "true" }
Могут ли логи изменений быть автоматически распарсены?
%p
Это сложно, потому что люди соблюдают сильно различающиеся форматы
и используют разные имена файлов.
%p
#{link_to "Vandamme", data.links.vandamme} — это gem для Ruby, созданный командой
Gemnasium и способный парсить логи изменений во многих (но не всех)
проектах с открытым исходным кодом.
%h4#yanked
%a.anchor{ href: "#yanked", aria_hidden: "true" }
Что насчёт yanked-выпусков?
%p
Yanked-выпуски — это версии, которые пришлось изъять из обращения из-за
серьёзного бага или проблем с безопасностью. Часто такие версии даже
не обозначают в логах изменений. А следовало бы. И вот как вам следует их
обозначать:
%p ## [0.0.5] - 2014-12-13 [YANKED]
%p
Тег [YANKED]
так бросается в глаза неспроста. Очень важно,
чтобы люди его заметили. Поскольку он заключён в квадратные скобки,
его также проще распарсить программно.
%h4#rewrite
%a.anchor{ href: "#rewrite", aria_hidden: "true" }
Следует ли вам когда-либо переписывать лог изменений?
%p
Конечно. Всегда есть веские причины для усовершенствования лога изменений.
Я регулярно подаю pull request’ы на добавление недостающих выпусков в проекты
с открытым исходным кодом, которые оставили свои логи изменений без сопровождения.
%p
К тому же, возможно, вы обнаружите, что в примечании к версии
забыли рассмотреть одно из критичных изменений. Важность того,
что в этом случае вы обновите ваш лог изменений, очевидна.
%h4#contribute
%a.anchor{ href: "#contribute", aria_hidden: "true" }
Как я могу помочь вашему проекту?
%p
Этот документ — не истина в последней инстанции; это моё
тщательно обдуманное мнение наряду с информацией и примерами, которые я собрал.
%p
Дело в том, что я хочу, чтобы наше сообщество пришло к согласованному мнению.
Я верю, что дискуссия так же важна, как и конечный результат.
%p
Так что, пожалуйста, #{link_to "участвуйте", data.links.repo}.
.press
%h3 Обсуждения
%p
Я приходил на #{link_to "подкаст The Changelog", data.links.thechangelog}, чтобы поговорить о том,
почему maintainer’ам (персоналу сопровождения) и контрибуторам следует озаботиться
ведением логов изменений, а также о мотивах, стоящих за этим проектом.