Generated output format¶
GenerateFromRepo returns a markdown string. This is exactly what it contains — no
template, no configuration, no way to change any of it short of post-processing the string
yourself.
The shape of one release¶
# v1.2.0
### Features
* **cli:** add a --json flag
* add the greeting command
### Bug Fixes
* **http:** retry on 503
- Release heading:
#(level 1), holding the tag name exactly as it appears in the repository. A tag named1.0.0produces# 1.0.0; thevis not added. - Category heading:
###(level 3). There is no level-2 heading anywhere in the output. - Entries:
*bullets. With a scope,* **scope:** description. Without one,* description. - Blank lines: one after the release heading, one after each category heading, and one between releases. The string ends with a newline after the last bullet.
Order of everything¶
Unreleasedfirst, if any commit is not reachable from a tag. The literal stringUnreleasedis used as the version.- Tagged releases, newest first, ordered by semver — so
v1.10.0precedesv1.9.0, whatever order the tags were created in. - Categories within a release, always in this order, with empty ones omitted: Breaking Changes → Features → Bug Fixes → Performance Improvements → Other.
- Entries within a category, newest commit first by committer time.
What is not in the output¶
No commit hashes, dates, authors, links, compare URLs, issue references or contributor
lists. No document title — there is no leading # Changelog heading, so the first line of
the string is the first release heading. No footnotes and no front matter.
The output is deliberately the same information a Changelog value holds, which is why it
round-trips through Parse. Anything richer would be
information the parser cannot read back.
The empty and near-empty cases¶
| Situation | Output |
|---|---|
| Repository with no commits | "" — empty string, nil error |
Repository whose every commit was dropped (all test/ci, or all unrecognised) |
"", nil error |
| Commits but no tags | A single # Unreleased section |
| A release whose commits were all dropped | The release is omitted entirely — no heading |
| Two tags on the same commit | The lower semver keeps the entries; the higher is emitted as a heading with no body |
That last pair is worth reading twice. A tag whose commits were all test/ci disappears
from the changelog without trace, while a tag that collided with another on the same commit
gets an empty section. Both are deliberate; neither is configurable.
Writing the output somewhere¶
GenerateFromRepo returns a string and nothing else. It does not write a file, does not
know the name CHANGELOG.md, and does not merge with an existing changelog — if you
regenerate, you are producing the whole document again from history, and it is your
program's job to decide what to do with it.