Python Commitizen Conventional Commits — Core Concepts
What Commitizen Does
Commitizen is a Python CLI tool that enforces the Conventional Commits specification and automates version bumps and changelog generation based on your commit history. It bridges the gap between human commits and machine-readable release metadata.
Install it:
pip install commitizen
The Conventional Commits Format
Every commit message follows this structure:
<type>(<scope>): <description>
[optional body]
[optional footer(s)]
Common types:
| Type | Meaning | Version Impact |
|---|---|---|
feat | New feature | Minor bump (1.0 → 1.1) |
fix | Bug fix | Patch bump (1.0.0 → 1.0.1) |
docs | Documentation only | No bump |
refactor | Code change, no behavior change | No bump |
perf | Performance improvement | Patch bump |
test | Adding/fixing tests | No bump |
ci | CI configuration | No bump |
BREAKING CHANGE | In footer, or ! after type | Major bump (1.x → 2.0) |
Example commits:
feat(auth): add OAuth2 login support
fix(api): handle null response from payment gateway
feat(search)!: change query parameter from 'q' to 'query'
The ! after the scope signals a breaking change inline.
Interactive Commit with cz commit
Instead of memorizing the format, let Commitizen guide you:
cz commit
It presents a step-by-step wizard:
- Select the type (feat, fix, docs…)
- Enter the scope (optional)
- Write a short description
- Add a longer body (optional)
- Note any breaking changes (optional)
The result is a perfectly formatted commit message every time.
Automatic Version Bumps
cz bump
This command:
- Reads all commits since the last version tag
- Determines the bump type based on commit types
- Updates version strings in configured files
- Creates a Git tag
- Updates the changelog
Configure which files contain version strings in pyproject.toml:
[tool.commitizen]
name = "cz_conventional_commits"
version = "1.2.0"
version_files = [
"src/mypackage/__init__.py:__version__",
"pyproject.toml:version"
]
tag_format = "v$version"
Changelog Generation
cz changelog
Generates a CHANGELOG.md grouped by version and commit type:
## v1.2.0 (2026-03-28)
### Feat
- **auth**: add OAuth2 login support
- **search**: add full-text search endpoint
### Fix
- **api**: handle null response from payment gateway
- **cache**: fix TTL calculation for negative values
Enforcing Commits with Pre-Commit
Add Commitizen as a pre-commit hook to reject non-conforming messages:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/commitizen-tools/commitizen
rev: v3.29.0
hooks:
- id: commitizen
Now any commit that doesn’t match the Conventional Commits pattern is rejected with a clear error message.
Common Misconception
“Conventional Commits means you can’t write expressive commit messages.” The convention applies to the first line only. The body and footer are free-form. You can write paragraphs explaining why a change was needed, link to issues, or describe the alternatives you considered. The structure is in the label, not the story.
One thing to remember: Commitizen makes versioning deterministic — your commit messages define what the next version number will be, removing the guesswork from releases.
See Also
- Python Black Formatter Understand Black Formatter through a practical analogy so your Python decisions become faster and clearer.
- Python Bumpversion Release Change your software's version number in every file at once with a single command — no more find-and-replace mistakes.
- Python Changelog Automation Let your git commits write the changelog so you never forget what changed in a release.
- Python Ci Cd Python Understand CI CD Python through a practical analogy so your Python decisions become faster and clearer.
- Python Cicd Pipelines Use Python CI/CD pipelines to remove setup chaos so Python projects stay predictable for every teammate.