From e3e31369a74343daa8edd0b77b1a1714f713701c Mon Sep 17 00:00:00 2001 From: mtkennerly Date: Fri, 15 Sep 2023 02:02:35 +0800 Subject: [PATCH] #67: Fix cases where log.excludeDecoration is configured --- CHANGELOG.md | 5 +++++ dunamai/__init__.py | 12 +++++++----- tests/integration/test_dunamai.py | 27 ++++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4d1f7c..ebc5346 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## Unreleased + +* For Git 2.16+, `--decorate-refs=refs/tags/` is now specified for `git log` + in case you've configured `log.excludeDecoration=refs/tags/`. + ## v1.18.0 (2023-07-10) * Added a `vcs` attribute to `Version` to indicate which VCS was detected. diff --git a/dunamai/__init__.py b/dunamai/__init__.py index fc55bd8..7ad2ae1 100644 --- a/dunamai/__init__.py +++ b/dunamai/__init__.py @@ -474,18 +474,20 @@ def normalize_tag_ref(ref: str) -> str: return "refs/tags/{}".format(ref) @staticmethod - def from_git_tag_topo_order(tag_branch: str) -> Mapping[str, int]: - code, logmsg = _run_cmd( + def from_git_tag_topo_order(tag_branch: str, git_version: List[int]) -> Mapping[str, int]: + cmd = ( "git log --simplify-by-decoration --topo-order --decorate=full" ' {} "--format=%H%d"'.format(tag_branch) ) - tag_lookup = {} + if git_version >= [2, 16]: + cmd += " --decorate-refs=refs/tags/" + code, logmsg = _run_cmd(cmd) - # Simulate "--decorate-refs=refs/tags/*" for older Git versions: filtered_lines = [ x for x in logmsg.strip().splitlines(keepends=False) if " (" not in x or "tag: " in x ] + tag_lookup = {} for tag_offset, line in enumerate(filtered_lines): # lines have the pattern # (tag: refs/tags/v1.2.0b1, tag: refs/tags/v1.2.0) @@ -1158,7 +1160,7 @@ def from_git( ) detailed_tags = [] # type: List[_GitRefInfo] - tag_topo_lookup = _GitRefInfo.from_git_tag_topo_order(tag_branch) + tag_topo_lookup = _GitRefInfo.from_git_tag_topo_order(tag_branch, git_version) for line in msg.strip().splitlines(): parts = line.split("@{") diff --git a/tests/integration/test_dunamai.py b/tests/integration/test_dunamai.py index 44aaa34..ea18c6e 100644 --- a/tests/integration/test_dunamai.py +++ b/tests/integration/test_dunamai.py @@ -4,7 +4,7 @@ import time from contextlib import contextmanager from pathlib import Path -from typing import Callable, Iterator, Optional +from typing import Callable, Iterator, List, Optional import pytest @@ -15,6 +15,12 @@ def avoid_identical_ref_timestamps() -> None: time.sleep(1.2) +def lacks_git_version(version: List[int]) -> bool: + if shutil.which("git") is None: + return True + return _get_git_version() < version + + REPO = Path(__file__).parent.parent.parent @@ -451,6 +457,25 @@ def test__version__from_git__shallow(tmp_path) -> None: Version.from_git(strict=True) +@pytest.mark.skipif(lacks_git_version([2, 27]), reason="Requires Git 2.27+") +def test__version__from_git__exclude_decoration(tmp_path) -> None: + vcs = tmp_path / "dunamai-git-exclude-decoration" + vcs.mkdir() + run = make_run_callback(vcs) + from_vcs = make_from_callback(Version.from_git) + b = "master" + + with chdir(vcs): + run("git init") + (vcs / "foo.txt").write_text("hi") + run("git add .") + run("git commit --no-gpg-sign -m Initial") + run("git tag v0.1.0 -m Release") + run("git config log.excludeDecoration refs/tags/") + + assert from_vcs() == Version("0.1.0", dirty=False, branch=b) + + @pytest.mark.skipif(shutil.which("git") is None, reason="Requires Git") def test__version__not_a_repository(tmp_path) -> None: vcs = tmp_path / "dunamai-not-a-repo"