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 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/commitizeTo 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://...).
export OPENROUTER_API_KEY=sk-or-...
git add -p # stage what you want to commit
commitize # generate a message, review it, commitYou'll see the staged file summary and the generated message, then a prompt:
Commit with this message? [y/e/r/n]
y— commit as-ise— edit the message in$EDITORfirstr— regeneraten— 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.logTo 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.
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 printingConfig lives in two places, merged together (repo-local wins):
- Global:
commitize config path --global(e.g.~/.config/commitize/config.toml) - Repo-local:
.commitize.tomlat 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 $EDITORExample 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 = 15Add 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 --localList configured providers with commitize providers list.
git clone https://github.com/quadram-institute-bioscience/commitize
cd commitize
uv sync --extra dev
uv run pytest