Most changelogs are either missing or useless ("updated things"). Raw git log output is worse — a wall of imperative verbs that no stakeholder wants to read. This prompt turns a commit range into a grouped, readable changelog that's ready for GitHub Releases, a team update, or a PR description.
The key insight: a changelog is for users of the code, not authors. "Search now filters by category" beats "Add category param to filterEntries()".
The prompt
Replace [range] with your commit range before running — e.g., v1.2.0..HEAD, main..HEAD, or --since="2 weeks ago".
Generate a changelog from the git history. Follow these steps:
## Steps
1. Run `git log [range] --oneline --no-merges` to get the commits.
2. Read each commit. If a commit message is unclear, run `git show <sha> --stat` to understand what changed.
3. Group commits into these categories:
- **Added** — new features or capabilities
- **Changed** — modifications to existing behavior
- **Fixed** — bug fixes
- **Removed** — removed features or deprecated code
- **Infrastructure** — CI/CD, dependencies, config, build changes
4. Within each category, write one bullet per logical change. Combine related commits into a single bullet if they represent one coherent change across multiple commits (e.g., a feature built across 3 commits becomes one bullet).
## Format
## [version or date]
### Added
- Description of what was added and why it matters
### Changed
- Description of what changed
### Fixed
- Description of what was broken and how it was fixed
### Infrastructure
- Description of infra/config changes
## Rules
- Omit empty categories
- Write from the user's perspective, not the developer's
- One bullet per logical change — don't split one feature across multiple bullets, and don't combine unrelated changes into one bullet
- Keep bullets to one sentence. Add a second only if the "why" isn't obvious
- Don't include merge commits or version bump commits
- For squash-merged PRs, treat the PR as one logical change — don't expand into its individual commits
Examples
Raw commits:
a1b2c3d feat: add category filter to AI toolkit
d4e5f6a fix: search input loses focus on mobile
7g8h9i0 chore: upgrade tailwind to 3.4
b1c2d3e feat: add copy button to toolkit code blocks
e4f5g6h fix: RSS feed missing toolkit entries
Generated changelog:
## 2026-02-22
### Added
- AI Toolkit entries can now be filtered by category (prompt, skill, technique, etc.)
- Code blocks in toolkit entries have a copy-to-clipboard button
### Fixed
- Search input no longer loses focus on mobile after typing
- RSS feed now includes AI Toolkit entries alongside blog posts
### Infrastructure
- Upgraded Tailwind CSS to 3.4
Common ranges
Since last tag:
git log $(git describe --tags --abbrev=0)..HEAD --oneline --no-merges
Branch diff (for a PR):
git log main..HEAD --oneline --no-merges
Last sprint (2 weeks):
git log --since="2 weeks ago" --oneline --no-merges
When to use it
- Before tagging a release — the output is ready to paste into GitHub Releases
- For PRs with many commits — faster than writing the description by hand
- Team updates — when a non-technical stakeholder asks "what shipped this week?"
When NOT to use it
- For a single-commit PR — just write the PR description yourself
- When commits don't have meaningful messages and you didn't write the code — Claude will guess wrong. Fix the commit messages first, or use the Explain Diff prompt which reads the actual code changes instead of relying on commit messages.
Tips
- If commits don't follow conventional prefixes (feat/fix/chore), Claude can still categorize by reading the diffs — it just takes longer.
- For repos that squash-merge PRs, each merge commit is already a logical unit. The changelog practically writes itself.