Skip to main content

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.

Conventional Commits format

The basic structure of a Conventional Commit:
<type>(<scope>): <description>

[optional body]

[optional footer(s)]

Example commits

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:
feat
features
New features or capabilities
feat(ui): add dark mode toggle
feat: implement user dashboard
feat(api): add rate limiting
Appears in: Features section
fix
bug fixes
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
docs
documentation
Documentation changes
docs: update API reference
docs(readme): add contributing guidelines
docs: fix typos in quickstart guide
Appears in: Documentation section
style
style
Code style changes (formatting, whitespace)
style: format code with prettier
style(css): improve button styling
Appears in: Style section
refactor
refactoring
Code refactoring without changing behavior
refactor(auth): simplify token validation
refactor: extract duplicate logic to utility
Appears in: Refactoring section
perf
performance
Performance improvements
perf(db): optimize query performance
perf: add caching layer for API responses
Appears in: Performance section
test
tests
Test additions or updates
test(api): add integration tests
test: improve coverage for edge cases
Appears in: Tests section
build
build
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
ci/cd
CI/CD configuration changes
ci: add GitHub Actions workflow
ci(docker): optimize build caching
Appears in: CI/CD section
chore
chores
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

feat(ui): implement real-time notifications

Added WebSocket support for live updates.
Users see changes instantly without refreshing.

Bug fixes

fix(security): patch SQL injection vulnerability

Sanitized user input in search queries.
All user-provided data now properly escaped.

Documentation

docs(api): add authentication examples

Added code samples for all auth methods.
Includes cURL, Python, and JavaScript examples.

Refactoring

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:
1

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"
2

Generate release notes

gitreleasegen generate --unreleased --format markdown
3

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

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
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
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
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.

Tools and resources

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