Skip to content

cz changelog picks the previous tag by date, not ancestry #2083

Description

@Dzarda7

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions