Description
cz changelog treats the newest tag by creatordate as the previous release. That is wrong when two version lines are released in parallel.
get_tags() always sorts with --sort=-creatordate:
https://github.com/commitizen-tools/commitizen/blob/master/commitizen/git.py
get_tags() already has reachable_only (git tag --merged), but cz changelog calls git.get_tags() without it. get_next_tag_name_after_version() then returns the next name in that date-sorted list, even if it is not an ancestor of HEAD.
get_latest_tag_name() already uses ancestry (git describe --abbrev=0 --tags). Changelog generation does not.
Example
We maintain v4 and v5 on the same repo (espressif/esptool):
| Tag |
Released |
v5.3.1 |
2026-06-29 |
v4.12.0 |
2026-07-14 |
v5.4.0 |
2026-09-02 |
cz changelog for v5.4.0 used v4.12.0 as the start tag (newer by date) and generated notes from v4.12.0 to v5.4.0 — i.e. most of the 5.x history, not just v5.3.1..v5.4.0.
git describe --abbrev=0 HEAD^ correctly yields v5.3.1.
Workaround
Pass --start-rev from the nearest ancestor tag:
CZ_ARGS=()
if PREVIOUS_TAG="$(git describe \
--tags \
--abbrev=0 \
HEAD^ \
--match 'v[0-9]*.[0-9]*.[0-9]*' \
--exclude '*.dev*' 2>/dev/null)"; then
CZ_ARGS=(--start-rev "${PREVIOUS_TAG}")
fi
cz changelog "${CZ_ARGS[@]}" --file-name changelog_body.md
Expected
The previous tag for a changelog should be the nearest reachable version tag (ancestry), not the newest tag by date.
Description
cz changelogtreats the newest tag bycreatordateas the previous release. That is wrong when two version lines are released in parallel.get_tags()always sorts with--sort=-creatordate:https://github.com/commitizen-tools/commitizen/blob/master/commitizen/git.py
get_tags()already hasreachable_only(git tag --merged), butcz changelogcallsgit.get_tags()without it.get_next_tag_name_after_version()then returns the next name in that date-sorted list, even if it is not an ancestor ofHEAD.get_latest_tag_name()already uses ancestry (git describe --abbrev=0 --tags). Changelog generation does not.Example
We maintain
v4andv5on the same repo (espressif/esptool):v5.3.1v4.12.0v5.4.0cz changelogforv5.4.0usedv4.12.0as the start tag (newer by date) and generated notes fromv4.12.0tov5.4.0— i.e. most of the 5.x history, not justv5.3.1..v5.4.0.git describe --abbrev=0 HEAD^correctly yieldsv5.3.1.Workaround
Pass
--start-revfrom the nearest ancestor tag:Expected
The previous tag for a changelog should be the nearest reachable version tag (ancestry), not the newest tag by date.