Skip to content

Commit Check

Clean commits. Clear standards.

Get started

Commit Check

One config, enforced everywhere

Write the policy once. The same rules run on a developer's laptop, in CI, and in whatever your AI agent is committing on your behalf.

$ commit-check --message --branch
CC003 subject-imperative check failed ==> docs: revamped the profile
Commit message should use imperative mood (e.g., 'fix bug' not 'fixed bug')
Suggest: Change the first verb to imperative form
Docs: https://commit-check.com/rules/#cc003
.pre-commit-config.yaml
repos:
  - repo: https://github.com/commit-check/commit-check
    rev: v2.13.0
    hooks:
      - id: check-message
      - id: check-branch
      - id: check-author-email
.github/workflows/commit-check.yml
- uses: commit-check/commit-check-action@v2
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  with:
    message: true
    branch: true
    pr-comments: ${{ github.event_name == 'pull_request' }}
MCP server
{
  "mcpServers": {
    "commit-check": {
      "command": "uvx",
      "args": ["commit-check-mcp"]
    }
  }
}

Why it exists

Git history is a database that every team writes to and almost nobody validates.

The cost shows up later, and indirectly. Release notes get written by hand because commit subjects cannot be grouped. git bisect walks through merge commits that record nothing but a sync. A commit is attributed to ec2-user because a build box had no user.name. A contribution has to be rejected months after the fact because it never carried a Signed-off-by trailer.

None of these are caught by a linter, a type checker, or a test suite. They are all caught by review — which means inconsistently, by whoever happens to be looking, and only after the work is done.

Commit Check treats commit metadata the way linters treat code: a policy written down once, enforced identically everywhere, with a stable identifier for every diagnostic so findings can be discussed, cited, and tracked.

  • One config


    A single cchk.toml drives the CLI, the pre-commit hook, the GitHub Action and the MCP server. There is no second place where the rules can disagree with themselves.

  • Fails where it is cheap


    The same check that runs in CI runs in your commit-msg hook. A malformed subject costs a second locally, or a full CI cycle plus a force-push remotely.

  • Stable rule IDs


    Every rule has an ID like CC003 that never changes once released. Cite it in a review comment, link to its documentation, suppress it per-rule.

  • Built to be trusted


    SLSA Level 3 build provenance with artifact attestation you can verify before installing. A failure names the rule, quotes the offending value, and says how to fix it.

What it checks

  • Commit messages


    Conventional Commits by default, or your own pattern. Subject length, mood, capitalisation, required body, forbidden merge/fixup/WIP commits.

    CC001–CC013

  • Branch names


    Conventional Branch naming, plus rebase checks that catch a branch drifting behind its target before CI wastes a run on stale code.

    CC201–CC202

  • Committer identity


    Catch commits authored by ec2-user on a build box, or require everyone to contribute from a company address.

    CC101–CC102

  • Signoff and DCO


    Require the Signed-off-by trailer locally, so contributors find out before CI rejects the pull request.

    Policy guides

  • AI attribution


    Whatever your project has decided about AI-assisted commits, enforce it mechanically instead of relitigating it in review.

    Policy guides

  • Org-wide policy


    Inherit a base config from a shared repository, then let each project override only what it needs.

    Integrations

What it is not

Commit Check is deliberately narrow: it validates metadata, not code.

  • Not a code linter. It never reads your source files.
  • Not a replacement for review. It enforces the mechanical rules so review can spend its attention on the change itself.
  • Not opinionated by default. Most rules are off until you turn them on. See the rules reference for what applies out of the box.

It is a lightweight, open alternative to GitHub Enterprise metadata restrictions and Bitbucket's paid Yet Another Commit Checker, without requiring a particular forge or an enterprise plan. If you already run ruff, eslint or golangci-lint on your source, Commit Check is the equivalent for the commits that carry it.

Ecosystem

One policy engine, multiple enforcement surfaces. Write your cchk.toml once — every surface reads the same file.

graph TB
    subgraph Policy["📄 cchk.toml"]
        direction LR
        Config[One policy file]
    end

    subgraph Engine["⚙️ commit-check<br/>(Python core)"]
        direction LR
        CLI[CLI & pre-commit]
        API[Python API]
    end

    subgraph Surfaces["🚀 Enforcement surfaces"]
        Action[commit-check-action<br/>GitHub Action]
        MCP[commit-check-mcp<br/>MCP Server]
    end

    Config --> Engine
    CLI --> Action
    API --> MCP
    Action --> CI[CI Pipeline]
    MCP --> Agent[AI Coding Agent]
  • commit-check


    Core engine — Python CLI, library and pre-commit hooks. Runs every validation the other surfaces expose.

    Getting started Repo

  • commit-check-action


    GitHub Action — CI integration that posts results as check runs, job summaries and pull request comments.

    Guide Repo

  • commit-check-mcp


    MCP server — exposes the validations as structured tools for AI coding agents such as Claude Code, Cursor and Copilot.

    Repo

Trusted by developers worldwide

Used by developers and organizations worldwide in their production workflows.

Apache Apache
Discovery Unicamp Discovery Unicamp
Texas Instruments Texas Instruments
OpenCADC OpenCADC
Extrawest Extrawest
Chainlift Chainlift
Mila Mila
RLinf RLinf
Istio Ecosystem Istio Ecosystem
Juniper Networks Juniper Networks
French National Parks French National Parks
OpenDriveLab OpenDriveLab
UT Austin RobIn UT Austin RobIn
WorldArena2 WorldArena2
moniqo moniqo
elu mobility elu mobility
Open Energy Platform Open Energy Platform
Collective Collective

And many more.

Ready in two minutes

$ pip install commit-check
$ commit-check --message --branch

No configuration file needed to start — sensible defaults apply immediately, and you tighten them when you are ready.

Get started Rules reference


Join our community

Be part of a growing ecosystem of developers who care about Commit Check.

GitHub Issue GitHub Pull Request