git-cliff

2.12.0 · active · verified Fri Apr 17

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.

Common errors

Warnings

Install

Imports

Quickstart

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)

view raw JSON →