Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(tags): add support for finding latest matching tag for incomplet…
…e version
  • Loading branch information
YazdanRa committed Dec 30, 2025
commit 6d94ba727c7d88e79da7b4bf4b84e70c26510e84
19 changes: 19 additions & 0 deletions commitizen/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,25 @@ def find_tag_for(
) -> GitTag | None:
"""Find the first matching tag for a given version."""
version = self.scheme(version) if isinstance(version, str) else version
release = version.release

# If the requested version is incomplete (e.g., "1.2"), try to find the latest
# matching tag that shares the provided prefix.
if len(release) < 3:
matching_versions: list[tuple[Version, GitTag]] = []
for tag in tags:
try:
tag_version = self.extract_version(tag)
except InvalidVersion:
continue
if tag_version.release[: len(release)] != release:
continue
matching_versions.append((tag_version, tag))

if matching_versions:
_, latest_tag = max(matching_versions, key=lambda vt: vt[0])
return latest_tag

possible_tags = set(self.normalize_tag(version, f) for f in self.tag_formats)
candidates = [t for t in tags if t.name in possible_tags]
if len(candidates) > 1:
Expand Down
37 changes: 37 additions & 0 deletions tests/test_tags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from commitizen.git import GitTag
from commitizen.tags import TagRules


def _git_tag(name: str) -> GitTag:
return GitTag(name, "rev", "2024-01-01")


def test_find_tag_for_partial_version_returns_latest_match():
tags = [
_git_tag("1.2.0"),
_git_tag("1.2.2"),
_git_tag("1.2.1"),
_git_tag("1.3.0"),
]

rules = TagRules()

found = rules.find_tag_for(tags, "1.2")

assert found is not None
assert found.name == "1.2.2"


def test_find_tag_for_full_version_remains_exact():
tags = [
_git_tag("1.2.0"),
_git_tag("1.2.2"),
_git_tag("1.2.1"),
]

rules = TagRules()

found = rules.find_tag_for(tags, "1.2.1")

assert found is not None
assert found.name == "1.2.1"