Overview
GitReleaseGen automatically categorizes commits based on the Conventional Commits specification. This structured format makes release notes more organized and meaningful.
While GitReleaseGen works with any commit format, using Conventional Commits produces the best results with automatic categorization and breaking change detection.
The basic structure of a Conventional Commit:
<type>(<scope>): <description>
[optional body]
[optional footer(s)]
Example commits
Feature
Bug fix
Breaking change
Documentation
feat(auth ): add OAuth2 authentication
Implements OAuth2 flow with JWT tokens for secure user sessions.
Supports multiple providers including Google and GitHub.
Commit types
GitReleaseGen recognizes these commit types and organizes them into sections:
New features or capabilities feat(ui ): add dark mode toggle
feat: implement user dashboard
feat(api ): add rate limiting
Appears in: Features section
Bug fixes and error corrections fix(parser ): handle multiline commit messages
fix: resolve memory leak in background tasks
fix(ui ): correct button alignment
Appears in: Bug Fixes section
Documentation changes docs: update API reference
docs(readme ): add contributing guidelines
docs: fix typos in quickstart guide
Appears in: Documentation section
Code style changes (formatting, whitespace) style: format code with prettier
style(css ): improve button styling
Appears in: Style section
Code refactoring without changing behavior refactor(auth ): simplify token validation
refactor: extract duplicate logic to utility
Appears in: Refactoring section
Performance improvements perf(db ): optimize query performance
perf: add caching layer for API responses
Appears in: Performance section
Test additions or updates test ( api ): add integration tests
test : improve coverage for edge cases
Appears in: Tests section
Build system and dependency changes build: upgrade to webpack 5
build(deps ): bump pytest from 7.0 to 8.0
Appears in: Build section
CI/CD configuration changes ci: add GitHub Actions workflow
ci(docker ): optimize build caching
Appears in: CI/CD section
Maintenance tasks and miscellaneous chore: update dependencies
chore(release ): bump version to 2.0.0
Appears in: Chores section
Scopes
Scopes provide additional context about what part of the codebase changed:
feat(api ): add authentication endpoint
fix(ui ): resolve button styling
docs(readme ): update installation steps
Common scopes:
api - API changes
ui - User interface
cli - Command-line interface
db - Database
auth - Authentication
docs - Documentation
tests - Testing
Choose scopes that make sense for your project. Consistency is more important than having many scopes.
Controlling scope display
Show or hide scopes in release notes:
# With scopes (default)
gitreleasegen generate --include-scopes
# Output: "**api**: Add authentication endpoint"
# Without scopes
gitreleasegen generate --no-include-scopes
# Output: "Add authentication endpoint"
Breaking changes
Breaking changes can be indicated in two ways:
Method 1: Exclamation mark
feat(api ) ! : change authentication flow
This changes the authentication from API keys to OAuth2.
feat(api ): change authentication flow
BREAKING CHANGE: API key authentication is removed.
All clients must migrate to OAuth2.
Both methods create a Breaking Changes section in release notes.
Breaking changes appear prominently in release notes to alert users about incompatible changes.
Examples by category
Features
User-facing feature
API feature
Infrastructure feature
feat(ui ): implement real-time notifications
Added WebSocket support for live updates.
Users see changes instantly without refreshing.
Bug fixes
Critical fix
UI fix
Data fix
fix(security ): patch SQL injection vulnerability
Sanitized user input in search queries.
All user-provided data now properly escaped.
Documentation
API documentation
Guide updates
docs(api ): add authentication examples
Added code samples for all auth methods.
Includes cURL, Python, and JavaScript examples.
Refactoring
Code improvement
Structure change
refactor(parser ): extract commit parsing logic
Moved parsing to dedicated module.
Improved testability and maintainability.
Complete example workflow
Here’s how Conventional Commits work in a real project:
Make changes and commit
# Feature commit
git commit -m "feat(auth): add Google OAuth integration"
# Bug fix commit
git commit -m "fix(api): handle timeout errors gracefully"
# Breaking change commit
git commit -m "feat(api)!: migrate to GraphQL
BREAKING CHANGE: REST endpoints removed.
See migration guide at docs/migration-v2.md"
Generate release notes
gitreleasegen generate --unreleased --format markdown
Review organized output
## Release v2.0.0
### Breaking Changes
- **api** : Migrate to GraphQL (abc123)
REST endpoints removed. See migration guide.
### Features
- **auth** : Add Google OAuth integration (def456)
### Bug Fixes
- **api** : Handle timeout errors gracefully (ghi789)
Commits are automatically organized into sections based on their type.
Best practices
Use descriptive commit messages
Good: feat(auth ): add two-factor authentication
Implements TOTP-based 2FA with QR code generation.
Supports authenticator apps like Google Authenticator.
Avoid: feat: add stuff
feat: updates
fix: bug fix
Be consistent with scopes
Define scopes for your project and use them consistently: # Good - consistent scopes
feat(api ): add endpoint
feat(ui ): add component
feat(db ): add migration
# Avoid - inconsistent scopes
feat(api ): add endpoint
feat(frontend ): add component
feat(database-layer ): add migration
Include context in commit body
feat(search ): implement full-text search
Added PostgreSQL full-text search for user queries.
- Indexed title and description fields
- Supports phrase matching with quotes
- Average query time: < 50ms
- Handles 1M+ records efficiently
fix(api ): resolve rate limiting bug (#123)
Fixed calculation error in token bucket algorithm.
Closes #122
Related to #115
Use breaking changes sparingly
Only mark commits as breaking when they truly require user action: # Breaking - requires migration
feat(api ) ! : change response format to camelCase
BREAKING CHANGE: All API responses now use camelCase.
Update your client code accordingly.
# Not breaking - backward compatible
feat(api ): add new optional parameter
Added optional 'filter' parameter to /api/users.
Existing clients continue to work without changes.
Converting existing commits
If your project doesn’t use Conventional Commits:
Option 1: Start today
Begin using Conventional Commits for new commits while keeping existing history as-is:
# From now on, use Conventional Commits
git commit -m "feat(api): add new endpoint"
Option 2: Rewrite history (use with caution)
For personal projects or before pushing:
# Interactive rebase to edit messages
git rebase -i HEAD~10
# In the editor, mark commits to reword:
# reword abc123 Old commit message
# reword def456 Another old message
# Update each commit to Conventional Commits format
Never rewrite history on shared branches. Only do this for private work.
Option 3: Manual categorization
GitReleaseGen does its best to categorize non-conventional commits, but results may vary.
Integration with GitReleaseGen
Automatic categorization
# These commits:
feat(ui ): add dashboard
fix(api ): resolve bug
docs: update readme
chore: bump dependencies
# Become this output:
## Release
### Features
- **ui** : Add dashboard
### Bug Fixes
- **api** : Resolve bug
### Documentation
- Update readme
### Chores
- Bump dependencies
Breaking change detection
# This commit:
feat(api ) ! : change authentication
BREAKING CHANGE: API keys no longer supported.
Use OAuth2 instead.
# Creates this section:
### Breaking Changes
- **api** : Change authentication (abc123)
API keys no longer supported. Use OAuth2 instead.
Conventional Commits spec Official specification and guidelines
Commitlint Lint commit messages in CI/CD
Commitizen Interactive commit message helper
Git hooks Enforce format with pre-commit hooks
Commitlint integration
Enforce Conventional Commits in your project:
# Install commitlint
npm install --save-dev @commitlint/{config-conventional,cli}
# Configure
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
# Add hook
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
Now commits must follow Conventional Commits format:
git commit -m "feat: add feature" # ✓ Passes
git commit -m "add feature" # ✗ Fails
Next steps
Examples See Conventional Commits in action
CLI reference Learn about scope display options
GitHub integration Link commits to pull requests
Configuration Customize commit processing