Skip to content

Repository files navigation

commitize

Generate git commit messages from your staged diff using an LLM, review them, and commit — all from one command. OpenRouter works out of the box; any other OpenAI-compatible API (OpenAI, Groq, local Ollama, etc.) can be configured too.

Install

Install straight from GitHub, no clone needed:

# with uv (recommended): installs the `commitize` command in its own isolated env
uv tool install git+https://github.com/quadram-institute-bioscience/commitize

# or with pipx
pipx install git+https://github.com/quadram-institute-bioscience/commitize

# or with pip, in a virtualenv
pip install git+https://github.com/quadram-institute-bioscience/commitize

To try it once without installing: uvx --from git+https://github.com/quadram-institute-bioscience/commitize commitize. To upgrade later: uv tool upgrade commitize (or pip install -U git+https://...).

Quick start

export OPENROUTER_API_KEY=sk-or-...
git add -p                 # stage what you want to commit
commitize                  # generate a message, review it, commit

You'll see the staged file summary and the generated message, then a prompt:

Commit with this message? [y/e/r/n]
  • y — commit as-is
  • e — edit the message in $EDITOR first
  • r — regenerate
  • n — abort, nothing is committed

The release command generates a changelog from commits since the last release tag (git tags ending in -release). It groups changes under headings "New features", "Bug fixes", and "Other changes", using an LLM to summarise and deduplicate. If the changelog file exists, new changes are prepended as a new release section while preserving existing content.

If nothing is staged, commitize falls back to analysing your unstaged changes (tracked modifications and untracked files) and proposes to stage them and commit. Files listed in a .commitize-ignore file at the repo root are skipped.

# .commitize-ignore (same glob-ish syntax as .gitignore)
*.log
build/
!keep.log

Repository context

To help the model pick the right type, scope and wording, commitize also sends the subjects of the last 15 commits (commit.recent_commits; 0 disables it). You can add guidance for your repository in a .commitize-context.md file at the repo root. The model treats it as rules from the maintainers:

weatherctl: a CLI that fetches and prints weather forecasts.

Scopes: net (everything under src/weatherctl/transport/), render, readme.
README and image changes are `docs`, never `feat`.
When a change fixes a GitHub issue named in the code, end the subject with "(#N)".

Only the first 4000 bytes are sent (commit.max_context_bytes). Like the diff, this file goes to your LLM provider, so don't put secrets in it.

Usage

commitize                 # same as `commitize commit`
commitize commit --yes    # skip the confirmation prompt
commitize commit --all    # stage tracked modifications first (like `git commit -a`)
commitize commit --dry-run           # print the message, don't commit
commitize commit --provider openai   # use a different configured provider
commitize commit --model gpt-4o      # override the model for this run
commitize commit --summary "Remove dead code"   # tell the LLM what the main change is
commitize commit --verbose  # show provider/model, and the session cost on OpenRouter
commitize release                  # generate a changelog since the last release
commitize release -o CHANGELOG.md  # write to file instead of printing

Configuration

Config lives in two places, merged together (repo-local wins):

  • Global: commitize config path --global (e.g. ~/.config/commitize/config.toml)
  • Repo-local: .commitize.toml at the root of the current git repo
commitize config init                                   # dump all defaults into the config file, ready to edit
commitize config init --local                           # ...into the repo-local .commitize.toml
commitize config show                                   # effective config + where each value came from
commitize config get providers.openrouter.model
commitize config set providers.openrouter.model openai/gpt-4o --global
commitize config set provider.default openai --local    # override for just this repo
commitize config edit --global                           # open the file in $EDITOR

Example config:

[provider]
default = "openrouter"

[providers.openrouter]
base_url = "https://openrouter.ai/api/v1"
api_key_env = "OPENROUTER_API_KEY"
model = "deepseek/deepseek-v4-flash"

[providers.openai]
base_url = "https://api.openai.com/v1"
api_key_env = "OPENAI_API_KEY"
model = "gpt-4o-mini"

[commit]
style = "conventional"     # or "plain"
confirm = true
max_diff_bytes = 8000
sign_off = false
ignore_file = ".commitize-ignore"
context_file = ".commitize-context.md"
max_context_bytes = 4000
recent_commits = 15

Add your own OpenAI-compatible provider (e.g. a local Ollama server) with:

commitize config set providers.local.base_url http://localhost:11434/v1 --global
commitize config set providers.local.model llama3.1 --global
commitize config set providers.local.api_key_env LOCAL_API_KEY --global
commitize config set provider.default local --local

List configured providers with commitize providers list.

Development

git clone https://github.com/quadram-institute-bioscience/commitize
cd commitize
uv sync --extra dev
uv run pytest

About

Demo Python package to generate commit messages using AI

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages