Хорошие способы управлять журналом изменений, используя git?

214

Я уже некоторое время использую Git и недавно начал использовать его для маркировки своих выпусков, чтобы мне было легче отслеживать изменения и видеть, какая версия работает у каждого из наших клиентов (к сожалению, код в настоящее время требует что у каждого клиента есть своя копия сайта PHP, я меняю это, но это медленно).

В любом случае, мы начинаем набирать обороты, я подумал, что было бы здорово показать людям, что изменилось с момента последнего релиза. Проблема в том, что я не веду журнал изменений, потому что не знаю, как это сделать. В это время я могу запустить журнал и создать его вручную, но это очень быстро утомит.

Я пробовал гуглить «git changelog» и «git manage changelog», но я не нашел ничего, что действительно говорило бы о процессе изменения кода и о том, как это совпадает с журналом изменений. В настоящее время мы следим за процессом разработки Рейн Хенрикс, и мне бы понравилось то, что с этим связано.

Есть ли стандартный подход, который мне не хватает, или это область, где каждый занимается своим делом?

Большое спасибо за ваши комментарии / ответы!

Topher Fangio
источник

Ответы:

181

Это было около 3-4 лет назад, но ради будущих искателей теперь возможно создавать великолепные журналы с:

git log --oneline --decorate

Или, если вы хотите, чтобы он был еще красивее (с цветом для терминала):

git log --oneline --decorate --color

Передача этого вывода в ChangeLog - это то, что я сейчас использую во всех своих проектах, это просто потрясающе.


источник
4
Еще один полезный тег --graph, который наглядно показывает, в каких ветвях находятся коммиты.
Eruant
44
Я бы настоятельно рекомендовал не использовать различия в журналах подарков
Оливье Лакан
4
копирование git logвывода в журнал изменений не имеет смысла. Вам нужно выполнить фильтрацию и редактирование, чтобы иметь читаемый журнал изменений, иначе зачем вам вообще нужен журнал изменений? Я думаю, что вы можете автоматизировать создание журнала изменений, но, пожалуйста, не делайте сырых копий git log!
Вааб
19
Проблема в том, что, даже если предположить, что каждый участник вашего проекта пишет четкие и читаемые сообщения о коммите, вы все равно будете генерировать «журнал изменений», содержащий тонны шума. Журналы изменений должны быть написаны с целью разъяснения к пользователям вашего проекта на заметные изменения , относящиеся к ним , которые произошли между выпусками, в то время как совершить сообщения должны быть направлены на разъяснение разработчикам , какие улучшения коммиттера марки в код . Иногда есть совпадение, но не всегда.
Ajedi32
7
Или, чтобы сделать это немного более конкретным, этот метод создаст «журнал изменений», содержащий множество записей, таких как «Исправлено написание fooMethod в ZModule» и «Refactor XModule для использования новой версии XYLibarary». Ваши пользователи не заботятся об этом. Они хотят знать , какие изменения были сделаны с их точки зрения , как пользователи, а не ваши перспективы в качестве разработчика. И это даже игнорирует такие вещи, как «Слияние PR # 123 из xdev / foo» и «Opps, исправлено newFeature, чтобы оно действительно работало», типа вещей, которые, вероятно, существуют в любом реальном репо.
Ajedi32
60

Вы можете использовать некоторую версию журнала git, чтобы помочь вам:

git log --pretty=%s                 # only print the subject

Если вы правильно называете свои ветки, так что слияние с мастером отображается как что-то вроде «Объединенная ветка Feature-Foobar», вы можете сокращать вещи, показывая только это сообщение, а не все маленькие коммиты, которые вы слили, которые вместе образуют характерная черта:

git log --pretty=%s --first-parent  # only follow first parent of merges

Возможно, вам удастся дополнить это собственным сценарием, который может делать такие вещи, как удаление битов «объединенной ветви», нормализация форматирования и т. Д. В какой-то момент вы, конечно, должны написать его самостоятельно.

Затем вы можете создать новый раздел для журнала изменений один раз для каждой версии:

git log [opts] vX.X.X..vX.X.Y | helper-script > changelogs/X.X.Y

и зафиксируйте это в вашей версии.

Если ваша проблема заключается в том, что эти темы коммитов не похожи на те, которые вы хотели бы поместить в журнал изменений, у вас есть два варианта: продолжать делать все вручную (и стараться не отставать от него более регулярно, вместо того, чтобы играть в ловушку). на момент релиза), или исправьте свой стиль сообщения коммита. Один из вариантов, если субъекты не собираются делать это за вас, заключался бы в размещении строк типа «изменить: добавленная функция foobar» в теле ваших сообщений о коммите, чтобы позже вы могли сделать что-то вроде того, git log --pretty=%B | grep ^change:чтобы получить только те супер Важные биты сообщений.

Я не совсем уверен, насколько больше, чем этот мерзавец может реально помочь вам создать ваши журналы изменений. Может быть, я неправильно истолковал, что вы подразумеваете под «управлять»?

Cascabel
источник
2
Это, безусловно, отличное начало, и я не думал о добавлении модификатора в тело, чтобы я мог использовать его позже. Это может быть тем, что я делаю. Спасибо за ответ! Если в течение следующего дня больше не будет ответов, я отмечу ваш ответ :-)
Topher Fangio
60

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я автор gitchangelog, о котором я буду говорить в следующем.

TL; DR: Вы можете проверить собственный журнал изменений gitchangelog или вывод ascii , сгенерировавший предыдущий.

Если вы хотите сгенерировать журнал изменений из вашей истории git, вам, вероятно, придется рассмотреть:

  • выходной формат . (Чистый пользовательский ASCII, тип журнала изменений Debian, Markdow, ReST ...)
  • некоторая фильтрация коммитов (вы, вероятно, не хотите, чтобы все опечатки или косметические изменения попадали в ваш список изменений)
  • некоторые передают текстовый спор перед включением в список изменений. (Обеспечение нормализации сообщений с использованием заглавных букв в первой букве или конечной точки, но это также может привести к удалению некоторой специальной разметки в сводке)
  • совместима ли ваша история с git ? Слияние, тегирование не всегда так легко поддерживается большинством инструментов. Это зависит от того, как вы управляете своей историей.

По желанию вам может потребоваться некоторая категоризация (новые вещи, изменения, исправления) ...

Имея все это в виду, я создал и использую gitchangelog . Он предназначен для использования соглашения о сообщениях git commit для достижения всех предыдущих целей.

Наличие соглашения о коммитах обязательно для создания хорошего журнала изменений (с использованием или без использования gitchangelog).

принятие сообщения

Ниже приведены предложения о том, что может быть полезно подумать о добавлении в ваши сообщения фиксации.

Возможно, вы захотите разделить ваши коммиты на большие разделы:

  • по намерению (например: новое, исправление, изменение ...)
  • по объектам (например: документ, упаковка, код ...)
  • по аудитории (например: dev, tester, users ...)

Кроме того, вы можете пометить некоторые коммиты:

  • как "второстепенные" коммиты, которые не должны отражаться в вашем списке изменений (косметические изменения, небольшая опечатка в комментариях ...)
  • как «рефакторинг», если у вас нет каких-либо существенных изменений функций. Таким образом, это также не должно быть частью журнала изменений, отображаемого конечным пользователем, например, но может представлять интерес, если у вас есть журнал изменений разработчика.
  • Вы также можете пометить «api», чтобы пометить изменения API или новые вещи API ...
  • ...и т.д...

Попробуйте написать сообщение о коммите, ориентируясь на пользователей (функциональность) как можно чаще.

пример

Это стандарт, git log --onelineчтобы показать, как эта информация может храниться:

* 5a39f73 fix: encoding issues with non-ascii chars.
* a60d77a new: pkg: added ``.travis.yml`` for automated tests. 
* 57129ba new: much greater performance on big repository by issuing only one shell command for all the commits. (fixes #7)
* 6b4b267 chg: dev: refactored out the formatting characters from GIT.
* 197b069 new: dev: reverse ``natural`` order to get reverse chronological order by default. !refactor 
* 6b891bc new: add utf-8 encoding declaration !minor 

Итак, если вы заметили, я выбрал формат:

{new|chg|fix}: [{dev|pkg}:] COMMIT_MESSAGE [!{minor|refactor} ... ]

Чтобы увидеть фактический результат вывода, вы можете заглянуть в конец страницы PyPI gitchangelog

Чтобы увидеть полную документацию моего соглашения о коммитах, вы можете увидеть справочный файл gitchangelog.rc.reference

Как создать из этого изысканный журнал изменений

Тогда довольно легко сделать полный список изменений. Вы можете сделать свой собственный сценарий довольно быстро, или использовать gitchangelog.

gitchangelogсгенерирует полный журнал изменений (с поддержкой секционирования как New, Fix...) и будет разумно настраиваться в соответствии с вашими собственными соглашениями о фиксации. Он поддерживает любой тип вывод , благодаря шаблонированию через Mustache, Mako templatingи имеет устаревшую систему по умолчанию письменного в сыре питона; все 3 современных движка имеют примеры того, как их использовать, и могут выводить журнал изменений, как тот, который отображается на странице PyPI в gitchangelog.

Я уверен , что вы знаете , что есть много других git logдля changelogинструментов там также.

vaab
источник
1
Это потрясающе, именно то, что я искал. Я попробую это, большое спасибо!
Джефф
26

А ближе к делу CHANGELOG. Скажи мне, если тебе нравится.

git log --since=1/11/2011 --until=28/11/2011 --no-merges --format=%B
Харшникет Сета
источник
Это вроде как: я бы добавил другие параметры --format, как описано в git-scm.com/docs/git-log#_pretty_formats
bluesmonk
23

gitlog-to-changelogСценарий пригодится для создания GNU-стиле ChangeLog.

Как показано gitlog-to-changelog --help, вы можете выбрать коммиты, используемые для генерации ChangeLogфайла, используя любую из опций --since:

gitlog-to-changelog --since=2008-01-01 > ChangeLog

или передавая дополнительные аргументы после --, которые будут переданы git-log(вызваны внутренне gitlog-to-changelog):

gitlog-to-changelog -- -n 5 foo > last-5-commits-to-branch-foo

Например, я использую следующее правило на верхнем уровне Makefile.amодного из моих проектов:

.PHONY: update-ChangeLog
update-ChangeLog:
    if test -d $(srcdir)/.git; then                         \
       $(srcdir)/build-aux/gitlog-to-changelog              \
          --format='%s%n%n%b%n' --no-cluster                \
          --strip-tab --strip-cherry-pick                   \
          -- $$(cat $(srcdir)/.last-cl-gen)..               \
        >ChangeLog.tmp                                      \
      && git rev-list -n 1 HEAD >.last-cl-gen.tmp           \
      && (echo; cat $(srcdir)/ChangeLog) >>ChangeLog.tmp    \
      && mv -f ChangeLog.tmp $(srcdir)/ChangeLog            \
      && mv -f .last-cl-gen.tmp $(srcdir)/.last-cl-gen      \
      && rm -f ChangeLog.tmp;                               \
    fi

EXTRA_DIST += .last-cl-gen

Это правило используется во время выпуска для обновления ChangeLogпоследними еще не записанными сообщениями о фиксации. Файл .last-cl-genсодержит идентификатор SHA1 самого последнего записанного коммита ChangeLogи хранится в репозитории Git. ChangeLogтакже записывается в хранилище, так что его можно редактировать (например, для исправления опечаток) без изменения сообщений фиксации.

Ролан Левилэйн
источник
Скрипт GCC Mklog также может быть интересным: stackoverflow.com/a/31606865/895245
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
Это должен быть проект-победитель! Почему у вас его нет на github?
Омер Даган
20

Поскольку создание тега для каждой версии является наилучшей практикой, вы можете разделить журнал изменений по версиям. В этом случае эта команда может помочь вам:

git log YOUR_LAST_VERSION_TAG..HEAD --no-merges --format=%B
bithavoc
источник
15

Для проектов GitHub это может быть полезно: github-changelog-generator

Он генерирует журнал изменений из тегов закрытых выпусков и объединенных pull-запросов.

Этот CHANGELOG.md был сгенерирован этим сценарием.

Пример:

Изменения

1.2.5 (2015-01-15)

Полный список изменений

Реализованные улучшения:

  • Используйте веху, чтобы указать, в какой версии ошибка была исправлена # 22

Исправлены ошибки:

  • Ошибка при попытке создать журнал для репо без тегов # 32

Объединенные запросы на извлечение:

  • Класс PrettyPrint включен в нижний регистр 'pp' # 43 ( schwing )

  • поддержка корпоративного github с помощью параметров командной строки # 42 ( glenlovett )

skywinder
источник
Такие проекты являются лучшими :) Какова была ваша мотивация сделать это? Также, благодаря вашему вдохновению, я сделал похожий инструмент, который работает без меток, разделяется на «Добавлено / Изменено / Исправлено / Удалено» и находится на PHP (мой «родной» язык): github.com/Symplify/ChangelogLinker Вы пишете посты о Changlogs ? Я хотел бы прочитать их
Томаш Вотруба
1
@ TomášVotruba спасибо за теплые слова. Это просто мое хобби. Я не много постил. Но я думаю, это того стоит. С наилучшими пожеланиями!
Skywinder
10

Я также сделал библиотеку для этого. Он полностью настраивается с помощью шаблона «Усы». Это может:

Я также сделал:

Подробнее о Github: https://github.com/tomasbjerre/git-changelog-lib

Из командной строки:

npx git-changelog-command-line -std -tec "
# Changelog

Changelog for {{ownerName}} {{repoName}}.

{{#tags}}
## {{name}}
 {{#issues}}
  {{#hasIssue}}
   {{#hasLink}}
### {{name}} [{{issue}}]({{link}}) {{title}} {{#hasIssueType}} *{{issueType}}* {{/hasIssueType}} {{#hasLabels}} {{#labels}} *{{.}}* {{/labels}} {{/hasLabels}}
   {{/hasLink}}
   {{^hasLink}}
### {{name}} {{issue}} {{title}} {{#hasIssueType}} *{{issueType}}* {{/hasIssueType}} {{#hasLabels}} {{#labels}} *{{.}}* {{/labels}} {{/hasLabels}}
   {{/hasLink}}
  {{/hasIssue}}
  {{^hasIssue}}
### {{name}}
  {{/hasIssue}}

  {{#commits}}
**{{{messageTitle}}}**

{{#messageBodyItems}}
 * {{.}} 
{{/messageBodyItems}}

[{{hash}}](https://github.com/{{ownerName}}/{{repoName}}/commit/{{hash}}) {{authorName}} *{{commitTime}}*

  {{/commits}}

 {{/issues}}
{{/tags}}
"

Или в Дженкинс:

введите описание изображения здесь

Томас Бьерре
источник
3
git log --oneline --no-merges `git describe --abbrev=0 --tags`..HEAD | cut -c 9- | sort

Это то, что я люблю использовать. Он получает все коммиты с момента последнего тега. cutизбавляется от хеша коммита. Если вы используете номера тикетов в начале ваших сообщений о коммите, они группируются с sort. Сортировка также помогает , если вы префикс некоторых коммитов с fix, typoи т.д.

orkoden
источник
3

Я позволил серверу CI передать следующее в файл с именем CHANGELOGдля каждого нового выпуска с датой, указанной в имени файла для выпуска:

>git log --graph --all --date=relative --pretty=format:"%x09 %ad %d %s (%aN)"
Лоренц Ло Зауэр
источник
2

Для журнала изменений стиля GNU я приготовил функцию

gnuc() {
  {
    printf "$(date "+%Y-%m-%d")  John Doe  <john.doe@gmail.com>\n\n"
    git diff-tree --no-commit-id --name-only -r HEAD | sed 's/^/\t* /'
  } | tee /dev/tty | xsel -b
}

С этим:

  • Я периодически фиксирую свои изменения для резервного копирования и перебазирования их перед окончательным редактированием в ChangeLog
  • затем запустите: gnuc

и теперь мой буфер обмена содержит что-то вроде:

2015-07-24  John Doe  <john.doe@gmail.com>

        * gdb/python/py-linetable.c (): .
        * gdb/python/py-symtab.c (): .

Затем я использую буфер обмена в качестве отправной точки для обновления ChangeLog.

Он не идеален (например, файлы должны быть относительно их пути ChangeLog, поэтому python/py-symtab.cбез него gdb/я буду редактировать gdb/ChangeLog), но это хорошая отправная точка.

Более продвинутые скрипты:

Я должен согласиться с Tromey: дублирование данных git commit в ChangeLog бесполезно.

Если вы собираетесь внести изменения, составьте хорошее резюме того, что происходит, возможно, как указано на http://keepachangelog.com/

Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
источник
2

Основанный на bithavoc , он перечисляет last tagдо HEAD. Но я надеюсь перечислить журналы между 2 тегами.

// 2 or 3 dots between `YOUR_LAST_VERSION_TAG` and `HEAD`
git log YOUR_LAST_VERSION_TAG..HEAD --no-merges --format=%B

Список журналов между 2 тегами.

// 2 or 3 dots between 2 tags
git log FROM_TAG...TO_TAG

Например, в нем будут перечислены журналы от v1.0.0до v1.0.1.

git log v1.0.0...v1.0.1 --oneline --decorate

AechoLiu
источник