mtkennerly / dunamai

Dynamic versioning library and CLI
https://dunamai.readthedocs.io/en/latest
MIT License
312 stars 24 forks source link

Inconsistent distance for non-matching tags #85

Closed aander80 closed 2 months ago

aander80 commented 2 months ago

Hello,

I have found what I believe to be a bug when calculating the distance in Git when the repo is tagged with a non-matching tag.

To reproduce this issue, run the following commands with dunamai 1.21.0.

cd $(mktemp -d)
git init
git commit -m "Initial commit" --allow-empty
git commit -m Dummy --allow-empty
git commit -m Dummy --allow-empty
dunamai from git # This will print 0.0.0.post3.dev0+<githash>
git tag hello HEAD^
dunamai from git # This will print 0.0.0.post2.dev0+<githash>
git --no-pager log

When HEAD^ is tagged with hello (which dunamai should not react to), the distance calculation changes; the distance is changed from 3 to 2.

From reading the dunamai source code, I gather that if no tags are found, the distance is calculated as the number of commits found in the history including the root commit with the command git rev-list --count HEAD. However, if tags are found but none are matched, then the distance is instead calculated as the number of commits between the root commit and the current commit but excluding the root commit, with the command git rev-list --count {}..HEAD".format(initial_commit). This causes the two dunamai calls above to generate two different versions. I would expect the distance to be the same in the two calls.

In the source code (pasted below), my best guess is that int(msg) should be replaced by int(msg) + 1

if matched_pattern is None:
    distance = 0

    code, msg = _run_cmd("git rev-list --max-parents=0 HEAD", path)
    if msg:
        initial_commit = msg.splitlines()[0].strip()
        code, msg = _run_cmd("git rev-list --count {}..HEAD".format(initial_commit), path)
        distance = int(msg) # Should this be incremented by 1?

As far as I can tell, this is only occurring when there are tags but no matching tags in the repo, otherwise the distance calculation seems to be correct from what I have seen in my (simple) tests.

mtkennerly commented 2 months ago

Thanks for catching this! It should just use git rev-list --count HEAD like the other cases. I guess I was overthinking when I implemented that 😅

aander80 commented 2 months ago

Thanks for the quick fix and the great tool!