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:

TypeMeaningVersion Impact
featNew featureMinor bump (1.0 → 1.1)
fixBug fixPatch bump (1.0.0 → 1.0.1)
docsDocumentation onlyNo bump
refactorCode change, no behavior changeNo bump
perfPerformance improvementPatch bump
testAdding/fixing testsNo bump
ciCI configurationNo bump
BREAKING CHANGEIn footer, or ! after typeMajor 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:

  1. Select the type (feat, fix, docs…)
  2. Enter the scope (optional)
  3. Write a short description
  4. Add a longer body (optional)
  5. Note any breaking changes (optional)

The result is a perfectly formatted commit message every time.

Automatic Version Bumps

cz bump

This command:

  1. Reads all commits since the last version tag
  2. Determines the bump type based on commit types
  3. Updates version strings in configured files
  4. Creates a Git tag
  5. 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.

pythongitrelease-managementdeveloper-tools

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.