conventional-git
Conventional Commits and Conventional Branch enforcement, validation, and generation
Contents
- About
- Key features
- Requirements
- Installation
- Usage
- Agents
- CLI reference
- Configuration
- Architecture
- Platform notes
- Documentation
- Contributing
- License
About
One rule runs on three surfaces:
- A deterministic Git hook enforces it for human contributors.
- Structured violations over MCP let agents self-correct.
- A CLI lets you validate and generate names and messages directly.
Key features
- Validate commits and branches with
code,field,message, andfix_hintfields. - Report
ERRORandWARNINGseverity. - Generate commit messages and branch names with
create. - Install Git hooks with
hook install. - Expose validation and convention details through MCP tools.
- Report installed extras, providers, and credential sources with
capabilities --json. - Store the vocabulary as CSV data.
- Adapt the rules for gitlint and commitizen.
- Distribute as a Claude Code plugin and an Agent Skills-compliant
skills/directory.
Requirements
- Git
- Python >=3.14
- uv to use the tool
- mise to contribute to the project
Installation
Install the tool from PyPI:
uv tool install conventional-git
conventional-git --help
Install optional features with extras:
uv tool install 'conventional-git[mcp,llm]'
Contributors can clone the repository and install the local package instead:
git clone https://github.com/gajaguar/conventional-git
cd conventional-git
uv tool install .
Install the gitlint extra to use the gitlint adapter for a repository that
already runs gitlint, or to check a whole commit range in CI — see
docs/gitlint/index.md. Install the llm extra to
enable the jev suggestion provider (see Suggest).
Usage
Validate
Validate a commit message with an option, a file, or standard input:
conventional-git check commit -m "feat: add login"
# commit: ok
conventional-git check commit -f .git/COMMIT_EDITMSG
printf 'feat: add login\n' | conventional-git check commit
The command exits with 0 for a valid message and 1 for a validation
failure. A warning is printed without changing the exit code when the report
remains valid.
Validate a branch by name or validate the current branch by default:
conventional-git check branch -n feat/add-login
# branch: ok
conventional-git check branch
The branch command uses the same exit codes. Trunk branches listed in
data/branch-trunks.csv (main, master, develop) are always valid and
skip the <type>/ requirement. So are branches that start with a prefix in
data/branch-exempt-prefixes.csv (dependabot/, renovate/): a bot names
those branches, and GitHub does not let you rename them.
Generate
Generate a commit message or branch name:
conventional-git create commit --type feat --description "add login"
# feat: add login
conventional-git create branch --type feature --description "add login"
# feature/add-login
Use --dry-run when you need the generated value without taking further
action. The current implementation prints the value in either mode.
Enforce
Install commit-msg, pre-commit, and pre-push hooks in a repository:
conventional-git hook install --target ../my-repo
Omit --target to use the current repository. See
docs/enforcement/index.md for how the
installer handles worktrees and core.hooksPath, wiring the hooks through
the pre-commit framework instead, and the CI recipe for re-checking after
--no-verify.
Suggest
Generate a commit suggestion from a diff. Without the llm extra or a
credential, create suggest always falls back to the built-in heuristic
provider and prints a notice; it never fails the command:
git diff --cached | conventional-git create suggest --diff-file -
conventional-git create suggest --diff-file changes.diff --apply
With the llm extra installed and a credential available, create suggest
prefers the jev provider (TypeSafe's Jev model, either called directly or
routed through OpenRouter):
conventional-git auth login --provider openrouter # or --provider typesafe
conventional-git create suggest --provider jev
The staged diff is sent to TypeSafe or OpenRouter. Enabling
jevmeans the diff text (and any secret staged in it) leaves the machine. Seedocs/suggestions/index.mdfor exactly what's sent, credential scope, and failure behavior before you enable it.
Python library
Import the rule modules and call their validators:
from conventional_git.branch import rules as branch_rules
from conventional_git.commit import rules as commit_rules
commit_report = commit_rules.validate_message("Added stuff.")
branch_report = branch_rules.validate_name("feat/add-login")
Each call returns a Report containing Violation objects.
MCP
Requires the mcp extra: pip install 'conventional-git[mcp]'. Serve the
Model Context Protocol over standard input and output:
conventional-git mcp serve
Without installing the extra, an editor or agent can still run it on demand:
uvx --from 'conventional-git[mcp]' conventional-git-mcp
The server exposes validate_commit_message, validate_branch_name,
describe_convention, and suggest_commit_message. See
docs/mcp/index.md.
Agents
The repository is both a Claude Code plugin and an
Agent Skills-compliant skills/
directory.
Claude Code — add the marketplace, then install the plugin (it bundles
conventional-commit, conventional-branch, and the MCP server):
/plugin marketplace add gajaguar/conventional-git
/plugin install conventional-git@conventional-git-skills
See docs/mcp/plugin-bundled-server.md
for how the bundled .mcp.json launches the server.
Any other agent that supports Agent Skills (Codex, Cursor, Gemini CLI, Copilot, ...):
npx skills add gajaguar/conventional-git
Skills call conventional-git capabilities --json before drafting, so they
only offer create suggest (see Suggest) when the llm extra
and a credential are both present, and never send a diff to a third party
without the user opting in through --suggest.
CLI reference
All commands return 0 on success. Validation failures and invalid input
return 1.
| Command | Options | Exit |
|---|---|---|
| check commit | -m, --message; -f, --file; --types-csv |
0 or 1 |
| check branch | -n, --name; --types-csv |
0 or 1 |
| create commit | --type; --description; --scope; --body; --breaking; --types-csv; --dry-run |
0 or 1 |
| create branch | --type; --description; --types-csv; --dry-run |
0 or 1 |
| create suggest | --diff-file; --provider; --apply |
0 or 1 |
| hook install | --target; --force |
0 or 1 |
| hook uninstall | --target |
0 |
| auth login | No command-specific options (requires the llm extra) |
0 or 1 |
| auth status | No command-specific options (requires the llm extra) |
0 or 1 |
| auth logout | No command-specific options (requires the llm extra) |
0 or 1 |
| capabilities | --json |
0 |
| mcp serve | No command-specific options (requires the mcp extra) |
Server status |
Use conventional-git <command> --help for the full option descriptions.
Configuration
Create .conventional-git.toml in the current repository:
| Key | Default | Purpose |
|---|---|---|
[commit] attribution_patterns |
built-in list | Extra attribution regexes |
[commit] type_overrides |
[] |
Extra commit types |
[branch] type_overrides |
[] |
Extra branch types |
[branch] trunk_overrides |
[] |
Extra trunk branch names |
[branch] exempt_prefix_overrides |
[] |
Extra exempt name prefixes |
Relative CSV paths in type_overrides / trunk_overrides /
exempt_prefix_overrides are resolved
against the directory containing .conventional-git.toml, not the process's
current directory. Every consumer that loads the file — the CLI, the MCP
server, and the gitlint adapter — honors it. See
docs/enforcement/attribution-trailers.md
for what attribution_patterns extends.
The --types-csv option extends the default vocabulary; it does not replace
it. Vocabulary files live in data/{commit,branch}-types.csv.
Architecture
flowchart TD
Core["Spec core: commit, branch, violations"]
Adapters["Adapters: gitlint, commitizen"]
Frontends["Front-ends: CLI, MCP, hooks"]
Core --> Adapters
Core --> Frontends
The spec core contains the rules and returns Report objects. Adapters map
violations to consumer tools. Front-ends map user or agent input to the core
and render its output. See docs/architecture/index.md.
.
├── pyproject.toml
├── mk/python.mk
├── mk/conventional-git.mk # conventional-git check and test targets
├── .pre-commit-hooks.yaml # hooks for other repositories
├── src/conventional_git/
│ ├── violations.py # Violation, Severity, Report
│ ├── commit/{grammar,rules,vocabulary}.py
│ ├── branch/{grammar,rules,vocabulary}.py
│ ├── config.py # .conventional-git.toml loader
│ ├── helpers.py
│ ├── generation/{heuristic,protocol,typesafe,credentials}.py
│ ├── data/{commit,branch}-types.csv
│ ├── adapters/{gitlint_rules,commitizen_config}.py
│ ├── cli/{app,auth,check,create,hook,mcp}.py
│ └── mcp/server.py
├── skills/conventional-{commit,branch}/SKILL.md
└── tests/
Platform notes
Git does not version .git/hooks, so each contributor installs the CLI and
runs hook install themselves rather than relying on a committed hook
script. A repository with core.hooksPath pointing elsewhere (for example
.husky/, set by another tool) still gets the hooks installed there — see
docs/enforcement/hook-install-path.md.
Documentation
docs/ is an OKF
bundle: one Markdown note per concept, indexed by
docs/index.md.
Contributing
mise install
make install
make check
make test
See CONTRIBUTING.md for the full workflow, and AGENTS.md for the coding rules an agent MUST follow.
License
Distributed under the MIT License. See LICENSE.
Metadata
Release files for conventional-git 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| conventional_git-1.2.0.tar.gz | 147.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| conventional_git-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 188.0 kB
Release files / conventional_git-1.2.0.tar.gz
| Download URL | conventional_git-1.2.0.tar.gz |
|---|---|
| Size | 147.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
37fc4242c02cb85855a9500ef7045e4e5e0e5a764f5949094df3282b58d037f5
|
|
BLAKE2b-256 checksum How to use checksums |
435b4079df321de64a9c231f54282d5affde251a05fa2e721104164c3f4da647
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency logRelease files / conventional_git-1.2.0-py3-none-any.whl
| Download URL | conventional_git-1.2.0-py3-none-any.whl |
|---|---|
| Size | 40.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
68d266eba75f2577bbd8f4ebfd366fc5e182b607afd9f2e9cba347c241f10793
|
|
BLAKE2b-256 checksum How to use checksums |
992a49b27dc061aaf47c4cd73271d81ecae79bfa1a6be93f8e1df7fdb57d356c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency log