{"id":9774,"library":"git-cliff","title":"git-cliff","description":"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.","status":"active","version":"2.12.0","language":"en","source_language":"en","source_url":"https://github.com/orhun/git-cliff","tags":["changelog","git","release notes","automation","conventional commits"],"install":[{"cmd":"pip install git-cliff","lang":"bash","label":"Install git-cliff"}],"dependencies":[],"imports":[{"symbol":"generate_changelog","correct":"from git_cliff import generate_changelog"}],"quickstart":{"code":"import os\nimport tempfile\nimport shutil\nimport subprocess\nfrom git_cliff import generate_changelog\n\n# Create a temporary directory to simulate a project environment\ntemp_dir = tempfile.mkdtemp()\noriginal_cwd = os.getcwd()\nos.chdir(temp_dir)\n\ntry:\n    # Initialize a dummy Git repository\n    subprocess.run([\"git\", \"init\", \"-b\", \"main\"], check=True, capture_output=True)\n    subprocess.run([\"git\", \"config\", \"user.name\", \"Test User\"], check=True, capture_output=True)\n    subprocess.run([\"git\", \"config\", \"user.email\", \"test@example.com\"], check=True, capture_output=True)\n\n    # Create some dummy commits with conventional commit messages\n    with open(\"file1.txt\", \"w\") as f:\n        f.write(\"initial content\")\n    subprocess.run([\"git\", \"add\", \".\"], check=True, capture_output=True)\n    subprocess.run([\"git\", \"commit\", \"-m\", \"feat: initial setup of the project\"], check=True, capture_output=True)\n\n    with open(\"file2.txt\", \"w\") as f:\n        f.write(\"more content\")\n    subprocess.run([\"git\", \"add\", \".\"], check=True, capture_output=True)\n    subprocess.run([\"git\", \"commit\", \"-m\", \"fix: resolve minor typo in file2\"], check=True, capture_output=True)\n\n    subprocess.run([\"git\", \"tag\", \"v1.0.0\"], check=True, capture_output=True)\n\n    with open(\"file3.txt\", \"w\") as f:\n        f.write(\"new feature\")\n    subprocess.run([\"git\", \"add\", \".\"], check=True, capture_output=True)\n    subprocess.run([\"git\", \"commit\", \"-m\", \"feat: implement new awesome feature\"], check=True, capture_output=True)\n\n    # Create a minimal .git-cliff.toml config file for predictable output\n    cliff_config_content = r\"\"\"\n[changelog]\nbody = \"\"\"\n{{% if version %}}\n## {{ version }} - {{ timestamp | date(format=\"%Y-%m-%d\") }}\n{{% else %}}\n## Unreleased\n{{% endif %}}\n{{% for group, commits in commits | group_by(attribute=\"group\") %}}\n### {{ group | upper_first }}\n{{% for commit in commits %}}\n- {{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end=\"\") }}]({{ commit.id }}))\n{{% endfor %}}\n{{% endfor %}}\n\"\"\"\n\n[git]\nfilter_commits = true\nconventional_commits = true\n\n[git.mapper]\nfeat = \"Features\"\nfix = \"Bug Fixes\"\n\"\"\"\n    with open(\".git-cliff.toml\", \"w\") as f:\n        f.write(cliff_config_content)\n\n    # Generate the changelog using the Python interface\n    # It will automatically discover the .git-cliff.toml config and the git repo\n    changelog_output = generate_changelog(\n        config_path=\".git-cliff.toml\" # Specify the config file explicitly\n    )\n    print(\"\\n--- Generated Changelog ---\\n\")\n    print(changelog_output)\n\nfinally:\n    # Clean up the temporary directory\n    os.chdir(original_cwd)\n    shutil.rmtree(temp_dir)\n","lang":"python","description":"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."},"warnings":[{"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.","message":"Starting 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.","severity":"breaking","affected_versions":">=2.0.0"},{"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.","message":"`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.","severity":"gotcha","affected_versions":"All versions"},{"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.","message":"The 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.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-17T00:00:00.000Z","next_check":"2026-07-16T00:00:00.000Z","problems":[{"fix":"Run `pip install git-cliff` to install the package.","cause":"The `git-cliff` Python package has not been installed in the current Python environment.","error":"ModuleNotFoundError: No module named 'git_cliff'"},{"fix":"Ensure your current working directory is inside a Git repository, or explicitly provide the `repository` argument to `generate_changelog` pointing to the Git repository's path.","cause":"The `git-cliff` command or `generate_changelog` function was executed in a directory that is not part of a Git repository, or outside the root of a repository.","error":"Error: failed to find a Git repository (or similar message from git-cliff)"},{"fix":"Carefully review your configuration file for TOML syntax errors (e.g., unmatched quotes, invalid keys, incorrect section headers). Refer to the official `git-cliff` documentation for example configurations.","cause":"The `.git-cliff.toml` (or `cliff.toml`) file contains syntax errors, is malformed, or is missing critical sections required by `git-cliff`.","error":"Error: Failed to parse configuration file: ... (e.g., invalid TOML syntax or missing required sections)"},{"fix":"Inspect the `body` section of your configuration file for common templating mistakes such as unmatched curly braces `{{ }}`, incorrect filter usage `|`, or invalid control flow statements `{% %}`. Consult Tera documentation or `git-cliff`'s template examples.","cause":"The `changelog.body` template in your `.git-cliff.toml` file contains syntax errors specific to the Tera templating language (which is similar to Jinja2).","error":"Error: template parsing failed: ... (followed by details related to Tera/Jinja2 syntax)"}]}