Skip to content

Generate from git history

GenerateFromRepo reads a repository's tags and commits and renders a changelog. It opens the repo with go-git (PlainOpenWithOptions with DetectDotGit), so the path can be the repo root or any subdirectory of it — no git binary is invoked.

func GenerateFromRepo(repoPath string, opts ...GenerateOption) (string, error)

The returned string is markdown, with releases newest-first and entries grouped by category within each release.

Bound the range

By default the output covers recent releases. Three options shape what is included:

// Only releases after a given tag.
md, err := changelog.GenerateFromRepo(".", changelog.WithSinceTag("v1.2.0"))

// Cap the number of releases emitted (newest first).
md, err = changelog.GenerateFromRepo(".", changelog.WithMaxReleases(10))

// Include the entire history, ignoring the default recency window.
md, err = changelog.GenerateFromRepo(".", changelog.WithIncludeAll())

Options combine — WithSinceTag sets the lower bound and WithMaxReleases caps the count within it.

How releases are ordered

Tags are validated as semver and ordered with golang.org/x/mod/semver, so the output is deterministic regardless of the order tags were created in the repo. A tag that is not valid semver is skipped for ordering purposes.

Unreleased commits

Commits after the most recent tag form the leading (unreleased) section, so a changelog generated mid-cycle still shows what has landed since the last release.

What each commit becomes

Every commit message is parsed as a Conventional Commit. The type selects a category (feat → feature, fix → fix, perf → performance, others → other), while test and ci are dropped. Scope and description are extracted, and breaking changes are flagged from both type!: and a BREAKING CHANGE: footer. The full rules are in Conventional Commits & categorisation.

Errors

Generation returns an error if the path is not a git repository or the history cannot be read. An empty repository (no commits) is handled gracefully rather than treated as an error.