Registry / devops / git-cliff

git-cliff

JSON →
library2.13.1pypypiunverified

git-cliff is a highly customizable changelog generator built in Rust with a convenient Python interface. It processes Git history to produce detailed, human-readable release notes based on conventional commits. Currently at version 2.12.0, the library maintains an active development pace with frequent updates and new features.

pip install git-cliff
INSTALL
IMPORT
SIG · GIT-CLIFF
G
git-cliff
devopspythonv2.13.1
Install
1.8s avg
Import
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v2.13.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.910 runs
installs and imports cleanly · install 0.0s · import 0.000s · 18.1MB
glibc
py 3.103.910 runs
installs and imports cleanly · install 1.8s · import 0.000s · 19MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

generate_changelog
from git_cliff import generate_changelog
from gitcliff import generate_changelog

This quickstart demonstrates how to generate a changelog using `git-cliff`'s Python interface. It creates a temporary Git repository with dummy commits and a minimal configuration file to ensure a self-contained and runnable example.

import os import tempfile import shutil import subprocess from git_cliff import generate_changelog # Create a temporary directory to simulate a project environment temp_dir = tempfile.mkdtemp() original_cwd = os.getcwd() os.chdir(temp_dir) try: # Initialize a dummy Git repository subprocess.run(["git", "init", "-b", "main"], check=True, capture_output=True) subprocess.run(["git", "config", "user.name", "Test User"], check=True, capture_output=True) subprocess.run(["git", "config", "user.email", "test@example.com"], check=True, capture_output=True) # Create some dummy commits with conventional commit messages with open("file1.txt", "w") as f: f.write("initial content") subprocess.run(["git", "add", "."], check=True, capture_output=True) subprocess.run(["git", "commit", "-m", "feat: initial setup of the project"], check=True, capture_output=True) with open("file2.txt", "w") as f: f.write("more content") subprocess.run(["git", "add", "."], check=True, capture_output=True) subprocess.run(["git", "commit", "-m", "fix: resolve minor typo in file2"], check=True, capture_output=True) subprocess.run(["git", "tag", "v1.0.0"], check=True, capture_output=True) with open("file3.txt", "w") as f: f.write("new feature") subprocess.run(["git", "add", "."], check=True, capture_output=True) subprocess.run(["git", "commit", "-m", "feat: implement new awesome feature"], check=True, capture_output=True) # Create a minimal .git-cliff.toml config file for predictable output cliff_config_content = r""" [changelog] body = """ {{% if version %}} ## {{ version }} - {{ timestamp | date(format="%Y-%m-%d") }} {{% else %}} ## Unreleased {{% endif %}} {{% for group, commits in commits | group_by(attribute="group") %}} ### {{ group | upper_first }} {{% for commit in commits %}} - {{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}]({{ commit.id }})) {{% endfor %}} {{% endfor %}} """ [git] filter_commits = true conventional_commits = true [git.mapper] feat = "Features" fix = "Bug Fixes" """ with open(".git-cliff.toml", "w") as f: f.write(cliff_config_content) # Generate the changelog using the Python interface # It will automatically discover the .git-cliff.toml config and the git repo changelog_output = generate_changelog( config_path=".git-cliff.toml" # Specify the config file explicitly ) print("\n--- Generated Changelog ---\n") print(changelog_output) finally: # Clean up the temporary directory os.chdir(original_cwd) shutil.rmtree(temp_dir)
git-cliff --version
Debug
Known issues
breakingStarting with `v2.0.0`, `git-cliff` officially transitioned its default configuration filename from `cliff.toml` to `.git-cliff.toml`. Existing configurations using the old filename may not be automatically discovered or used.
fix
Rename your configuration file from `cliff.toml` to `.git-cliff.toml`. Review the changelog for `v2.0.0` for any other potential syntax or section changes within the TOML structure that might require updates.
affects: >=2.0.0
gotcha`git-cliff` relies heavily on Git tags for version detection and changelog segmentation. If your repository lacks consistent tags (e.g., `v1.0.0`), the generated changelog might be incomplete, misleading, or include all history under an 'Unreleased' section.
fix
Adopt a consistent Git tagging strategy (e.g., semantic versioning like `vX.Y.Z`). Use `git tag` to verify existing tags. For generating changelogs for the latest commits without a tag, use arguments like `--unreleased` (if available via CLI or exposed in Python API) or generate to a specific tag range.
affects: All versions
gotchaThe Python interface is a direct binding to the underlying Rust core. This means that detailed error messages, especially those related to configuration file parsing or template rendering (which uses Tera, a Jinja2-like engine), often originate from the Rust side and might require familiarity with `git-cliff`'s CLI output for full interpretation.
fix
When debugging complex configuration or templating issues, try running `git cliff --verbose` directly in your terminal with the same configuration file. This often provides more granular diagnostics and stack traces from the Rust engine that can pinpoint the exact problem area.
affects: All versions
Upgrade
Version history
2.13.1latest on PyPI · released Apr 26, 2026
Audit
Dependencies

No dependency data recorded yet.

Agent activity
15 hits · last 30 days
node
14
Resources
git-cliff — pip install git-cliff · libregistry