使用 Git 管理变更日志有哪些好方法?

发布于 2024-09-15 07:14:00 字数 1703 浏览 5 评论 0 原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

请远离我 2024-09-22 07:14:00

那是在 2015 年,但为了未来的搜索者,现在可以通过以下方式生成华丽的日志:

git log --oneline --decorate

或者,如果您希望它更漂亮(带有终端的颜色):

git log --oneline --decorate --color

将该输出通过管道传输到 ChangeLog这是我目前在所有项目中使用的,它简直太神奇了。

This was in 2015, but for the sake of future searchers, it's now possible to generate gorgeous logs with:

git log --oneline --decorate

Or, if you want it even prettier (with color for the terminal):

git log --oneline --decorate --color

Piping that output to ChangeLog is what I currently use in all my projects, and it's simply amazing.

迷你仙 2024-09-22 07:14:00

您可以使用 git log 的一些风格来帮助您:

git log --pretty=%s                 # Only prints the subject

如果您很好地命名了您的分支,以便合并到 master 显示为类似“合并分支功能-foobar”的内容,您可以缩短时间通过仅显示该消息,而不是您合并的所有小提交,它们一起形成了该功能:

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

您也许可以使用自己的脚本来增强此功能,该脚本可以执行诸如删除“合并分支”位之类的操作,当然,在某些时候你必须自己编写它。

然后,您可以为每个版本的变更日志创建一个新部分:

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

并在您的版本发布提交中提交该部分。

如果您的问题是这些提交主题与您想要放入变更日志中的内容不同,那么您几乎有两个选择:继续手动完成所有操作(并尝试更定期地跟上它,而不是玩追赶游戏-在发布时更新),或者修复您的提交消息样式。

如果主题不打算为您执行此操作,一种选择是在提交消息的正文中放置诸如“change:added feature foobar”之类的行,以便稍后您可以执行诸如 git log 之类的操作--漂亮=%B | grep ^change: 仅抓取消息中那些超级重要的部分。

我不完全确定 Git 能真正帮助您创建变更日志多少。也许我误解了你所说的“管理”的意思?

You can use some flavor of git log to help you out:

git log --pretty=%s                 # Only prints the subject

If you name your branches nicely, so that a merge to master shows up as something like "Merged branch feature-foobar", you can shorten things by only showing that message, and not all the little commits that you merged, which together form the feature:

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

You might be able to augment this with a script of your own, which could do things like strip out the "Merged branch" bits, normalize formatting, etc. At some point you have to write it yourself though, of course.

Then you could create a new section for the changelog once per version:

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

And commit that in your version release commit.

If your problem is that those commit subjects aren't anything like what you'd want to put in a changelog, you pretty much have two options: keep doing everything manually (and try to keep up with it more regularly instead of playing catch-up at release time), or fix up your commit message style.

One option, if the subjects aren't going to do it for you, would be to place lines like "change: added feature foobar" in the bodies of your commit messages, so that later you could do something like git log --pretty=%B | grep ^change: to grab only those super-important bits of the messages.

I'm not entirely sure how much more than that Git could really help you create your changelogs. Maybe I've misinterpreted what you mean by "manage"?

十秒萌定你 2024-09-22 07:14:00

TL;DR:您可能需要检查 gitchangelog 自己的变更日志 或生成前一个的 ASCII 输出

如果您想从 Git 历史记录生成变更日志,您可能需要考虑:

  • 输出格式。 (纯自定义 ASCII,Debian 变更日志类型,降价休息 等)
  • 一些提交过滤(您可能不希望看到更改日志中出现所有拼写错误或修饰性更改)
  • 一些提交文本争论在包含之前在变更日志中。 (确保消息标准化为首字母大写或最后一个点,但它也可能会删除摘要中的一些特殊标记。)
  • 您的 Git 历史记录兼容吗?大多数工具并不总是那么容易支持合并和标记。这取决于您如何管理您的历史记录。

或者,您可能需要一些分类(新事物、更改、错误修复等)。

考虑到这一切,我创建并使用了 gitchangelog。它旨在利用 Git 提交消息约定来实现之前的所有目标。

创建良好的变更日志必须遵守提交消息约定(无论是否使用 gitchangelog)。

提交消息约定

以下是关于在提交消息中添加可能有用的内容的建议。

您可能希望将您的提交粗略地分成几个大的部分:

  • 按意图(例如:新的、修复、更改等)
  • 按对象(例如:文档、打包、代码等)
  • 按受众(例如:开发、 这些

此外,您可能希望将一些提交标记为“次要”提交,

  • 提交不应输出到您的变更日志(外观更改、注释中的小拼写错误等),
  • 如果您实际上没有任何重大的功能变化。因此,这也不应该成为向最终用户显示的变更日志的一部分,但如果您有开发人员变更日志,它可能会引起一些兴趣。
  • 您还可以使用“API”标记来标记 API 更改或新的 API 内容...
  • ...等等...

尝试通过尽可能频繁地定位用户(功能)来编写提交消息。

示例

这是标准的git log --oneline,用于显示如何存储此信息::

* 5a39f73 fix: encoding issues with non-ASCII characters.
* 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页面的末尾https://pypi.python.org/pypi/gitchangelog" rel="nofollow noreferrer">gitchangelog。

要查看我的提交消息约定的完整文档,您可以查看参考文件 gitchangelog.rc.reference

如何由此生成精美的变更日志

然后,制作完整的变更日志就很容易了。您可以很快地创建自己的脚本,或者使用 gitchangelog。

gitchangelog 将生成完整的变更日志(分段支持为 NewFix...),并且可以根据您自己的提交约定进行合理配置。由于通过 MustacheMako 模板 进行模板化,它支持任何类型的输出,并且有一个用原始 Python 编写的默认遗留引擎;当前的所有三个引擎都有如何使用它们的示例,并且可以输出更改日志,如 gitchangelog 的 PyPI 页面上显示的那样。

我相信您知道还有很多其他的 git logchangelog 工具。

免责声明:我是 gitchangelog 的作者我将在下面谈到这一点。

TL;DR: You might want to check gitchangelog's own changelog or the ASCII output that generated the previous.

If you want to generate a changelog from your Git history, you'll probably have to consider:

  • the output format. (Pure custom ASCII, Debian changelog type, Markdown, REST, etc.)
  • some commit filtering (you probably don't want to see all the typos or cosmetic changes getting in your changelog)
  • some commit text wrangling before being included in the changelog. (Ensuring normalization of messages as having a first letter uppercase or a final dot, but it could be removing some special markup in the summary also.)
  • is your Git history compatible?. Merging and tagging is not always so easily supported by most of the tools. It depends on how you manage your history.

Optionally, you might want some categorization (new things, changes, bugfixes, etc.).

With all this in mind, I created and used gitchangelog. It's meant to leverage a Git commit message convention to achieve all of the previous goals.

Having a commit message convention is mandatory to create a nice changelog (with or without using gitchangelog).

Commit message convention

The following are suggestions to what might be useful to think about adding in your commit messages.

You might want to separate roughly your commits into big sections:

  • by intent (for example: new, fix, change, etc.)
  • by object (for example: doc, packaging, code, etc.)
  • by audience (for example: dev, tester, users, etc.)

Additionally, you could want to tag some commits:

  • as "minor" commits that shouldn't get outputted to your changelog (cosmetic changes, a small typo in comments, etc.)
  • as "refactor" if you don't really have any significant feature changes. Thus this should not also be part of the changelog displayed to final user for instance, but it might be of some interest if you have a developer changelog.
  • you could tag also with "API" to mark API changes or new API stuff...
  • ...etc...

Try to write your commit message by targeting users (functionality) as often as you can.

Example

This is the standard git log --oneline to show how this information could be stored::

* 5a39f73 fix: encoding issues with non-ASCII characters.
* 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

So if you've noticed, the format I chose is:

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

To see an actual output result, you could look at the end of the PyPI page of gitchangelog.

To see a full documentation of my commit message convention, you can see the reference file gitchangelog.rc.reference.

How to generate an exquisite changelog from this

Then, it's quite easy to make a complete changelog. You could make your own script quite quickly, or use gitchangelog.

gitchangelog will generate a full changelog (with sectioning support as New, Fix...) and is reasonably configurable to your own committing conventions. It supports any type of output thanks to templating through Mustache, Mako templating, and has a default legacy engine written in raw Python; all current three engines have examples of how to use them and can output changelogs as the one displayed on the PyPI page of gitchangelog.

I'm sure you know that there are plenty of other git log to changelog tools out there also.

DISCLAIMER: I'm the author of gitchangelog of which I'll be speaking in the following.

明月松间行 2024-09-22 07:14:00

更切题的变更日志:

git log --since=1/11/2011 --until=28/11/2011 --no-merges --format=%B

A more to-the-point changelog:

git log --since=1/11/2011 --until=28/11/2011 --no-merges --format=%B
枯寂 2024-09-22 07:14:00

gitlog-to-changelog 脚本可以方便地生成 GNU 风格的 ChangeLog

gitlog-to-changelog --help所示,您可以使用选项--since选择用于生成ChangeLog文件的提交>:

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 包含 ChangeLog 中记录的最新提交的 SHA-1 标识符,并存储在 Git 存储库中。 ChangeLog 也记录在存储库中,以便可以对其进行编辑(例如纠正拼写错误)而无需更改提交消息。

The gitlog-to-changelog script comes in handy to generate a GNU-style ChangeLog.

As shown by gitlog-to-changelog --help, you may select the commits used to generate a ChangeLog file using either the option --since:

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

or by passing additional arguments after --, which will be passed to git-log (called internally by gitlog-to-changelog):

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

For instance, I am using the following rule in the top-level Makefile.am of one of my projects:

.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

This rule is used at release time to update ChangeLog with the latest not-yet-recorded commit messages. The file .last-cl-gen contains the SHA-1 identifier of the latest commit recorded in ChangeLog and is stored in the Git repository. ChangeLog is also recorded in the repository, so that it can be edited (e.g. to correct typos) without altering the commit messages.

夢归不見 2024-09-22 07:14:00

由于为每个版本创建一个标签是最佳实践,因此您可能希望对每个版本的变更日志进行分区。在这种情况下,此命令可以帮助您:

git log YOUR_LAST_VERSION_TAG..HEAD --no-merges --format=%B

Since creating a tag per version is the best practice, you may want to partition your changelog per version. In that case, this command could help you:

git log YOUR_LAST_VERSION_TAG..HEAD --no-merges --format=%B
一萌ing 2024-09-22 07:14:00

我还为此创建了一个库。它完全可以通过 Mustache 模板进行配置。可以:

  • 存储到文件中,例如 CHANGELOG.md
  • 发布到 MediaWiki
  • 或者只是打印 我还制作了标准输出

更多详细信息请参见 GitHub:https://github.com/tomasbjerre/git-changelog-lib< /a>

从命令行:

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}}
"

或者在 Jenkins 中:

在此处输入图像描述

I also made a library for this. It is fully configurable with a Mustache template. That can:

I also made:

More details are on GitHub: https://github.com/tomasbjerre/git-changelog-lib

From the command line:

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}}
"

Or in Jenkins:

Enter image description here

灯角 2024-09-22 07:14:00

我让 CI 服务器将以下内容通过管道传输到名为 CHANGELOG 的文件中对于每个新版本,其日期在版本文件名中设置:

git log --graph --all --date=relative --pretty=format:"%x09 %ad %d %s (%aN)"

I let the CI server pipe the following into a file named CHANGELOG for each new release with the date set in the release-filename:

git log --graph --all --date=relative --pretty=format:"%x09 %ad %d %s (%aN)"
通知家属抬走 2024-09-22 07:14:00

GNU 风格变更日志

对于 GNU 风格变更日志,我已经完善了该功能:

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

这样:

  • 在对变更日志进行最终编辑之前,我定期提交更改以备份和变基,
  • 然后运行: gnuc

现在我的剪贴板包含类似以下内容:

2015-07-24  John Doe  <[email protected]>

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

然后我使用剪贴板作为更新变更日志的起点。

它并不完美(例如,文件应该相对于其 ChangeLog 路径,因此 python/py-symtab.c 没有 gdb/ 因为我将编辑 gdb /ChangeLog),但这是一个很好的起点。

更高级的脚本:

不过,我必须同意 Tromey 的观点:在更改日志没有用。

如果您要制作变更日志,请对其进行良好的总结,可能如保留变更日志

GNU style changelog

For a GNU style changelog, I've cooked the function:

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

With this:

  • I commit my changes periodically to backup and rebase them before doing the final edit to the ChangeLog
  • then run: gnuc

and now my clipboard contains something like:

2015-07-24  John Doe  <[email protected]>

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

Then I use the clipboard as a starting point to update the ChangeLog.

It is not perfect (e.g., files should be relative to their ChangeLog path, so python/py-symtab.c without gdb/ since I will edit the gdb/ChangeLog), but it is a good starting point.

More advanced scripts:

I have to agree with Tromey though: duplicating Git commit data in the ChangeLog is useless.

If you are going to make a changelog, make it a good summary of what is going on, possibly as specified at Keep a Changelog.

裂开嘴轻声笑有多痛 2024-09-22 07:14:00
git log --oneline --no-merges `git describe --abbrev=0 --tags`..HEAD | cut -c 9- | sort

是我喜欢用的。它获取自最后一个标签以来的所有提交。 cut 删除提交哈希。如果您在提交消息的开头使用票证编号,它们将按 sort 分组。如果您在某些提交前加上 fixtypo 等前缀,排序也会有所帮助。

git log --oneline --no-merges `git describe --abbrev=0 --tags`..HEAD | cut -c 9- | sort

Is what I like to use. It gets all commits since the last tag. cut gets rid of the commit hash. If you use ticket numbers at the beginning of your commit messages, they are grouped with sort. Sorting also helps if you prefix certain commits with fix, typo, etc.

小…红帽 2024-09-22 07:14:00

基于bithavoc,下面列出了最后一个标签直到HEAD 。但我希望列出两个标签之间的日志。

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

列出两个标签之间的日志:

// Two or three dots between two tags
git log FROM_TAG...TO_TAG

例如,这将列出从 v1.0.0v1.0.1 的日志:

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

Based on bithavoc, the following lists the last tag until HEAD. But I hope to list the logs between two tags.

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

List logs between two tags:

// Two or three dots between two tags
git log FROM_TAG...TO_TAG

For example, this will list logs from v1.0.0 to v1.0.1:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文