Generate a changelog from git commits (without publishing garbage)
Your git history already knows what changed. The dream is obvious: run one command,
get a changelog. The tooling for this is genuinely good now β but teams that wire it up
usually end up with a changelog nobody reads, because they skipped the one manual step
that matters. This guide covers the tools and the step. (Want to try the idea
in ten seconds first? Paste a git log into our free
release notes generator β no signup, and it hands you a draft,
not a changelog, for exactly the reasons below.)
Level 0: plain git log
You don't need any tooling to get a first draft out of git:
# everything since the last tag, one line each, no merge noise
git log $(git describe --tags --abbrev=0)..HEAD --oneline --no-merges
# same, formatted as markdown bullets
git log $(git describe --tags --abbrev=0)..HEAD --no-merges --pretty='- %s'
That second one-liner pasted into a release note is already better than silence. Its weakness is its input: it's only as readable as your commit subjects.
Level 1: Conventional Commits
The Conventional Commits
convention prefixes every commit with a type β feat:, fix:,
docs:, chore:, with ! or a
BREAKING CHANGE: footer for breaking changes. Two real benefits:
- Machines can sort your history. Tools can group features
apart from fixes and drop
chore:noise entirely. - Machines can pick your next version.
fixβ patch,featβ minor, breaking β major (see semver in plain English).
The cost is discipline at commit time β enforce it with a commit-lint hook or don't bother; a half-followed convention generates half a changelog.
Level 2: the generators
- git-cliff β a fast, single-binary generator with templated output. Great when you want full control of the rendered markdown.
- conventional-changelog / standard-version β the original Node ecosystem tooling; writes CHANGELOG.md and bumps versions.
- release-please β runs in CI, maintains a rolling release PR whose description is the pending changelog; merging it tags the release.
- GitHub's "Generate release notes" β one click on a release, groups merged PRs by label. Zero setup, PR-title quality output.
All of these solve the same problem: turning commit subjects into grouped markdown. Pick whichever fits your CI; none of them solves the next problem.
The rule: generated output is a draft
A commit subject is written for your team, at the moment of the change, in
implementation vocabulary. A changelog entry is written for your users, at the
moment of release, in outcome vocabulary. No template closes that gap:
"fix: race in session refresh" needs a human to become
"you no longer get logged out mid-request." So treat generator output the way you treat
a first draft: keep the grouping, rewrite the five lines users will actually care about,
delete the rest. Five curated lines beat fifty accurate ones β that's the difference
between a changelog and release notes.
Wiring it up end to end
Wakelog's CLI has this pipeline built in. wakelog post --from-git collects
the commits since your last tag into a markdown draft (merges excluded, title from the
tag), and --draft holds it unpublished so you can do the curation pass on
the dashboard before flipping it live:
git tag v1.4.0
wakelog post --from-git --draft # curate on the dashboard, then publish
Prefer your existing generator? Pipe anything into it:
git cliff --latest | wakelog post -t "v1.4.0". Either way the result is a
hosted page, RSS feed, and embeddable widget β not a file at the bottom of your repo.
Start a changelog β free Next: how to write a changelog β
Related guides
- Release notes from Jira tickets: from issue tracker to changelog (without the ticket soup)
Jira has a release-notes button, and everyone who has pressed it knows the result. Turning tickets into a changelog people read: fix-version hygiene, the release-note field, translation rules, and telling the reporter their bug shipped. - AI-generated release notes: what to automate (and what to never delegate)
What to hand the model (compression, rewording, consistency), the failure modes that publish fiction, the draft-then-gate pipeline, and the promises only humans get to write. - Changelog linting: automated checks that catch bad release notes
Everything else you ship goes through CI; the changelog usually ships unreviewed. Which failures are mechanical enough to automate, where the check belongs (PR, release, cron), when to block vs. warn β and why a green lint run is a floor, not a ceiling.
Last updated 2026-07-29 Β· All guides