Maintaining clear, accurate, and structured project changelogs is essential for software engineering teams, open-source maintainers, and DevOps release workflows. Writing release notes manually by reading through raw git commits is tedious, inconsistent, and prone to overlooking critical bug fixes or breaking changes. The git-cliff command-line utility automates this by parsing Git commit history and generating highly customisable, Markdown-formatted changelogs in seconds.
Written in Rust, git-cliff reads Git repository trees, identifies Conventional Commits (such as feat:, fix:, and perf:), filters release tags, and renders structured CHANGELOG.md files using powerful Tera templating.
Why Choose git-cliff for Release Automation?
While basic tools like git log produce raw text, git-cliff provides enterprise-grade release document parsing:
- Full Conventional Commits Support: Automatically parses commit types, scopes, descriptions, breaking change footers, and linked GitHub/GitLab issue IDs.
- Tera Templating Engine: Customise the generated Markdown layout down to every heading, badge, link, and commit author using Tera templates (syntax identical to Jinja2).
- Blazing Fast Performance: Written in Rust, it parses repositories with tens of thousands of commits in under a second.
- CI/CD Integration: Integrates effortlessly into GitHub Actions, GitLab CI, and local pre-release Git hooks.
- Monorepo and Non-Conventional Support: Can filter commits by directory path for monorepos or parse custom regex patterns if your team does not strictly adhere to Conventional Commits.
How to Install git-cliff on Linux
The git-cliff binary is distributed across all primary Linux distribution package managers.
Arch Linux and Manjaro
Install directly from Arch Linux’s official repositories:
sudo pacman -S git-cliff
Ubuntu, Debian, and Linux Mint
Download the official pre-compiled .deb package from GitHub releases, or install via Cargo:
# Compiling via Cargo (Rust toolchain)
cargo install git-cliff
Alternatively, install via Homebrew on Linux:
brew install git-cliff
Fedora and RHEL Derivatives
Install via the community package archives or Cargo:
sudo dnf install git-cliff
Initializing Your Configuration File (cliff.toml)
Before generating release documentation, create a default configuration template:
- Navigate to your Git repository:
cd ~/projects/my-web-app - Generate a starter
cliff.tomlconfiguration:git-cliff --init - Inspect the generated
cliff.tomlfile. It configures commit parsers that categorize messages into standard sections:feat→ Featuresfix→ Bug Fixesperf→ Performance Improvementsrefactor→ Refactoringdoc→ Documentation
Generating Your First Automated Changelog
Once configured, producing publication-ready documentation takes a single command:
1. Previewing the Changelog in the Terminal
To inspect the generated changelog without writing to disk:
git-cliff
2. Generating the Full CHANGELOG.md File
To compile the complete history across all tagged releases into a Markdown file:
git-cliff -o CHANGELOG.md
3. Generating Release Notes for the Latest Tag Only
When drafting release notes for GitHub Releases or GitLab Tags, you only need notes for the most recent version bump:
git-cliff --latest
Or capture notes for an unreleased version that has not yet been tagged:
git-cliff --unreleased --tag 1.2.0
Common git-cliff Flags Reference
| Command Option | Function | Operational Use Case |
|---|---|---|
git-cliff -o <file> |
Output to file | Writes formatted documentation straight to CHANGELOG.md. |
git-cliff --latest |
Latest release notes | Generates body copy for GitHub Release modals. |
git-cliff --unreleased |
Collect unreleased commits | Previews upcoming changes prior to tagging a new release. |
git-cliff --prepend <file> |
Prepend new release | Adds new version notes to the top while preserving older manual edits. |
git-cliff --strip all |
Strip Markdown headers | Extracts raw bullet points for Slack or Teams release broadcasts. |
Customising Commit Parsing in cliff.toml
You can customise how commit messages are cleaned, filtered, and presented:
[git]
# Parse Conventional Commits
conventional_commits = true
# Filter out merge commits and chore updates
filter_unconventional = false
commit_parsers = [
{ message = "^feat", group = "Features" },
{ message = "^fix", group = "Bug Fixes" },
{ message = "^perf", group = "Performance Improvements" },
{ message = "^doc", group = "Documentation", skip = true },
{ message = "^chore\\(release\\)", skip = true },
]
By marking skip = true on routine dependency updates or internal documentation tweaks, your public release notes remain concise, relevant, and engaging for end users.