Automatic Changelog Generation from Git Commits — The Complete Guide
2026-06-01
title: "Automatic Changelog Generation from Git Commits — The Complete Guide" description: "Stop writing changelogs manually. Here is how to automatically generate human-readable changelogs from your git commits and pull requests." date: "2026-06-01" keywords: ["automatic changelog generator", "generate changelog from git commits", "github changelog automation", "automated changelog"] readTime: "11 min read" category: "Engineering"
Somewhere in your repository, there is a CHANGELOG.md that has not been touched in four months. Or there is no CHANGELOG.md at all, and you are making do with GitHub releases that say things like "bug fixes and performance improvements."
Your users know when you shipped something. They do not know what you shipped. Your stakeholders ask during planning what went out last month. Your enterprise customers need changelogs for compliance. Your open-source users want to know if the breaking change they are seeing is intentional.
Changelogs are important. Writing them is tedious. Automating them is straightforward.
Why Changelogs Matter
The changelog is not primarily for developers. Developers have git log. The changelog is for everyone else.
Users and customers need to know what changed between the version they are on and the version they are updating to. They need to understand if there are breaking changes, new features they should be using, or bugs that affected them that are now fixed.
Stakeholders and leadership use changelogs to understand shipping velocity. A well-maintained changelog is evidence that the team is shipping consistently and tracking their work.
Enterprise customers often require changelogs for security and compliance purposes. They need to be able to demonstrate to auditors that they evaluated what changed before updating a dependency.
Open-source contributors read changelogs to understand the project's trajectory and decide whether to invest time in contributing.
None of these people want to read git log --oneline. They want a structured, human-readable summary of what changed and what it means for them.
The Changelog Problem: Nobody Writes Them
The reason changelogs are usually empty or outdated is simple: writing one requires translating the history of what you did into the context of why it matters to someone who did not do it. That is hard to do in the moment and very hard to do retroactively.
Most teams attempt some version of the following after every release:
- Run
git log v1.2.0..v1.3.0 --onelineand stare at a list of commit messages - Try to organize those messages into Added, Changed, Fixed, Removed categories
- Translate developer-speak commit messages into user-facing language
- Realize you do not remember what half the commits were for
- Ship a changelog that covers the commits you remember and omits the ones you do not
This takes thirty to ninety minutes and produces a changelog that is incomplete, inconsistently formatted, and occasionally wrong about what the changes actually do.
Keep a Changelog Format: The Right Way to Structure a Changelog
Before we talk about automation, here is what a good changelog entry looks like. The Keep a Changelog standard is the most widely used and the most sensible:
# Changelog
All notable changes to this project will be documented in this file.
## [1.3.0] - 2026-06-01
### Added
- Users can now export their data as CSV from the account settings page
- New `/api/exports` endpoint for programmatic data export
- Rate limiting on authentication endpoints (100 requests per 15 minutes)
### Changed
- Dashboard now loads initial data in parallel, reducing time-to-interactive by 40%
- User search now returns results sorted by last-active date by default
### Fixed
- Fixed an issue where users with apostrophes in their names could not log in
- Fixed incorrect pagination count on the repository list page
### Security
- Updated dependencies to address CVE-2026-1234 in the image processing library
That is a good changelog entry. It is written for humans. It uses past tense. It describes what changed from the user's perspective. It separates types of changes clearly.
Writing this manually for every release is the problem. Generating it automatically from git history is the solution.
Conventional Commits and Their Limitations
Many teams adopt conventional commits as a step toward automated changelogs. The format is type(scope): description — for example, feat(auth): add magic link login or fix(api): handle null response from payment provider.
Tools like standard-version and semantic-release can then parse these commit messages and generate a changelog automatically.
This works, up to a point. The limitations are significant:
It requires buy-in from every developer on the team. One developer writing add stuff instead of feat: add stuff breaks the automation. Enforcing conventional commits requires tooling like commitlint and significant team discipline.
Commit messages are written for developers, not users. Even a perfect conventional commit message like feat(users): add CSV export to account settings is not the same thing as a changelog entry written for a user.
It only captures what developers remember to put in commit messages. Significant changes that happen across multiple commits are often underdocumented in the commit log.
It does not understand context. A tool that parses commit messages cannot explain that the "add pagination middleware" commit means "your app will now handle 10x more concurrent users."
Why Commit Messages Alone Are Not Enough
The deeper problem with commit-message-based changelogs is that commit messages describe implementation, not impact.
A developer writes refactor: extract auth logic to middleware because that is what they did. The impact on a user or stakeholder is something like "authentication is now faster and more consistent across all endpoints." Those are not the same sentence, and one of them is much more useful in a changelog.
Good changelog generation requires understanding the diff, not just the message. What files changed? What functions were added or removed? What does the pattern of changes suggest about the intent?
An AI model that reads the full diff and the commit messages together can produce a changelog entry that is both accurate and user-facing.
The Diff-Based Approach to Changelog Generation
Here is what the raw inputs look like and what gets generated from them:
# Raw git log for a recent push:
a3f2c1d feat: add pagination to /users endpoint
b4e3d2c fix: handle empty results in user search
c5f4e3b refactor: extract database queries to repository layer
d6g5f4e chore: update dependencies
That is what a commit-message-based changelog generator starts with. The result is usually a formatted list of the same messages.
What Pushpen starts with includes all of that plus:
- Which files changed in each commit
- What the actual code changes look like
- What the existing changelog says (so it can prepend, not replace)
- The full context of the repository
The generated changelog entry:
## [Unreleased] - 2026-06-01
### Added
- User list API now supports pagination — use the `page` and `limit`
query parameters to navigate large datasets
### Fixed
- User search now correctly handles repositories with no results,
previously returning an error
### Changed
- Internal database architecture refactored for improved performance
and maintainability (no user-facing changes)
The dependency update is omitted because it has no user-facing impact. The refactor is noted but correctly labeled as internal. The pagination feature is described from the user's perspective with the actual parameter names they need to know.
Comparison: Four Approaches to Changelog Generation
| Approach | Setup required | User-facing language | Accuracy | Automatic | |---|---|---|---|---| | Manual writing | None | Yes (when done well) | High | No | | git log formatting | None | No | Exact | No | | Conventional commits + tools | High (team discipline) | Partial | Depends on commit quality | Yes | | AI from diff (Pushpen) | Low (connect repo) | Yes | High | Yes |
The conventional commits approach occupies a middle ground that requires significant overhead and produces mediocre output. The AI diff approach requires almost no overhead and produces output that is actually useful.
How Pushpen Turns Messy Commits into Clean Changelogs
When you push to your repository, Pushpen receives the webhook event within seconds. It reads the commit messages, the file changes, and the existing CHANGELOG.md if one exists. It generates a new changelog entry in Keep a Changelog format and prepends it to the existing file.
If you are starting from scratch, it creates the CHANGELOG.md. If you already have one, it adds the new entry at the top while preserving all existing entries.
The output is a pull request with the updated changelog. You review it — which takes about two minutes — make any adjustments, and merge. Your changelog is always current, always human-readable, and always reflecting what you actually shipped.
For the technical details on how this integrates with GitHub webhooks, see the webhook automation deep dive. For the full picture on documentation automation, the complete guide to GitHub documentation automation covers all four doc types together.
Ship Changelogs Without Writing Them
Your users want to know what changed. Now they can, without any extra work from your team.
Tired of outdated codebases?
Start free →