Commitizen's bump does the version, the tag and the changelog, and its documented hook revision is a branch
Create committing rules for projects :rocket: auto bump versions :arrow_up: and auto changelog generation :open_file_folder:
At a glance
- What is it?
- Commitizen is a release tool that enforces a commit message convention, derives the next version from the commit history, and writes the changelog. Its install paths span five package managers, its Git requirement is stated to three decimal places, and its own dependency manifest still carries a marker for an interpreter it no longer supports.
- Who is it for?
- Commitizen is a sensible fit if your team already writes structured commits and wants the version, the tag and the changelog produced from them rather than maintained by hand. Three things to check before you wire it in.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 4, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One command produces the version, the tag and the changelog
The README reduces the tool to a single command, and that command has three side effects. Running it bumps the project's version, creates a git tag, and updates the changelog if the option for that is enabled, along with the version files. The version number is not typed in by you: it is derived from your commit history using semantic versioning, which is why the commit message convention is the load-bearing part of the whole design. Each of those three pieces is configurable separately, with dedicated documentation for version files, the version scheme and the version provider. The changelog follows a named format rather than an invented one, and the commit convention defaults to Conventional Commits. So the tool is really four defaults plus a set of escape hatches, and the defaults are the part you are agreeing to when you initialise it.
Five project install paths, two of them Poetry-era
Installation is split into a global route and a project route, and the project route has five branches. The global one is the recommended path through pipx or uv, both of which install into an isolated environment and both of which have a matching upgrade command:
# Install commitizen
uv tool install commitizen
# Keep it updated
uv tool upgrade commitizenHomebrew is offered for macOS. For a project there is plain pip, conda from a channel, uv with a development flag, and two different Poetry commands depending on the version you have: a group flag for Poetry at or above 1.2.0 and a development flag for anything older. The pattern manager route uses its own development flag syntax. None of these is wrong, but the fact that the Poetry line has to branch on version tells you how old the oldest supported Poetry is, and it is the kind of detail a copy-paste installer will get wrong silently rather than loudly.
The Git requirement is stated to three decimal places
The requirements section has two lines and the second one is remarkable. Python needs to be at 3.10 or newer, a floor the manifest also carries. Git needs to be at version 1.8.5.2 or newer. That is a patch-level Git version, from a long time ago, and it is not a typo in the sense of a stray character: it is the kind of precise floor that gets written when someone bisects a failure against an old Git and records the exact version that worked. Its practical effect is nil for anyone on a current machine, and its practical value is diagnostic, because if a bump fails for a reason that looks like Git itself you now have a specific version to compare against rather than a vague sense of new enough.
The documented hook revision is a branch, and the page tells you to change it
The pre-commit integration is presented in four steps and the second one is the interesting one. You add a repository block to your pre-commit configuration pointing at this project with a revision set to master, and a comment says to replace it with the latest tag. Then you install two hooks, and a table maps them: one runs at the commit message stage and the other at the pre-push stage. Then a note repeats the revision advice and offers a command that updates it automatically. So the sample configuration, copied verbatim, installs hooks from a moving branch rather than a pinned version, which is the opposite of what a hook is for. The second hook is the more interesting of the pair by name, since validating a branch name is a pre-push concern rather than a per-commit one.
The commands run a hook manager that is not the pre-commit tool
The section is titled as covering two integrations, and the install step gives you one command with two hook types. That command is not pre-commit. It belongs to a different tool, and the badge row at the top of the README links that tool's repository, while the configuration file it edits is named for pre-commit and the hook ids in it are the conventional ones. The practical reading is that this project supports both ecosystems through one manifest: the hook definitions live in the repository, the tool that consumes them is your choice, and the documentation happens to show the commands for one of them. If you use the other, the configuration block is still what you copy and the two stage names in the table still tell you where each hook runs.
A dependency marker survives for an interpreter the package refuses
The packaging metadata is careful and annotated, which makes one line stand out. It requires Python 3.10 or newer and, at the bottom of the dependency list, adds a backport of the standard library's metadata module with a marker restricting it to Python versions below 3.10. That marker can never be true given the requirement above it, so the dependency is dead weight that ships in the lock file and in every resolve. Two other lines show the same care: one excludes a single exact version of the prompt toolkit library with a comment explaining that it is a transitive dependency with a known issue upstream, and one pins the typing extensions backport to Python versions below 3.11. That last one is live. Somebody tidied the dependency list and missed one line, which is normal and harmless.
The package readme is a different file from the repository readme
The manifest points its readme field at a file under the documentation directory rather than at the readme you see on the forge. That means what a package index renders as the project's description is not this page, and the two can drift independently. The documentation itself is a static site built with its own tool and configured by a file at the root, and there is a separate configuration for a link checker, which is the kind of addition that arrives once a documentation site has broken a link in CI. The root also holds a configuration for a static analysis service, one for formatting this project's own TOML files, a manifest for packaging, a changelog, and an agent instructions file. The hooks directory at the root is the piece with functional weight: it is where the two hook implementations live.
Six commands and two aliases, and a preview flag built for automation
The quick reference table is the fastest way to see the surface. Initialising configuration has no alias. Committing has one. Bumping has none. Generating a changelog has an alias. Validating commit messages has none. Showing version information has none. Two details in the advanced section are worth more than the table. There is a project-version flag on the version command, so a script can ask for your version rather than the tool's own. And the changelog command has a dry-run mode that takes that version as its argument, which the README says is useful for automation and pipelines and suggests as a way to notify a chat channel about a new release. That pair turns the tool into a notification hook rather than only a release step.
Editorial conclusion
Commitizen is a sensible fit if your team already writes structured commits and wants the version, the tag and the changelog produced from them rather than maintained by hand. Three things to check before you wire it in. Pick the install path deliberately, because there are five and two of them differ only by Poetry version. Pin the hook revision rather than copying the sample, which points at a branch. And read what your commit messages will actually produce, since the version scheme and the changelog format are both configurable and the defaults assume one particular convention.
Frequently asked questions
What is Commitizen used for?
Release management. It enforces a commit message convention, defaulting to Conventional Commits, derives the next version from your commit history using semantic versioning, generates the changelog in a keep a changelog format, and tags the release, with the version files updated alongside.
how to install commitizen
Globally, pipx install commitizen or uv tool install commitizen are recommended, and brew install commitizen is offered for macOS. Inside a project there are five routes: pip, conda from the conda-forge channel, uv with a dev flag, a Poetry command that differs by Poetry version, and a pdm command with its own dev flag.
what is commitizen
A Python release management tool, invoked through a short command, that enforces standardized commit messages, bumps versions from the commit history, writes changelogs and creates tags. Custom rules and plugins can be added through pip, and the project requires Python 3.10 or newer.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/commitizen-tools-commitizen)