GitVersion icon indicating copy to clipboard operation
GitVersion copied to clipboard

[Bug] GitVersion does not seem to be deterministic

Open mglochsen opened this issue 4 years ago • 10 comments

Describe the bug When I execute some Git commands and GitVersion in the exact same way the resulting version numbers differ. In my case the result is sometimes the version 0.1.1 and rarely 0.2.0 (which I am expecting).

Expected Behavior

GitVersion should always return the same result.

Actual Behavior

GitVersion sometimes return 0.1.1 and rarely 0.2.0 (which I am expecting).

Possible Fix

I am not able to provide a fix.

Steps to Reproduce

I'll attach a zipped folder which contains a PowerShell-Script and some sample files which can be used to reproduce the issue. gitversion_issue.zip

The script can be run multiple times. What the script does (it's basically a GitFlow test):

  1. copies a sample file and my GitVersion.yml to a test run folder
  2. inits git and makes an initial commit
  3. creates a develop branch
  4. creates a feature branches an makes some changes there
  5. merges the feature branch back to develop
  6. creates a release branch for the version 0.1.0 and makes some changes there
  7. merges the release branch back to master
  8. executes dotnet-gitversion
  9. creates a tag for the version 0.1.0
  10. merges the release branch back to develop
  11. Repeats step 4-8 with a second feature branch and a release branch for the version 0.2.0
  12. executes dotnet-gitversion (this is the point where sometimes 0.1.1 and rarely 0.2.0 appears)

Context

I'm investigating an unexpected version behavior which might be my own fault and was trying to reproduce the issue by creating the attached script. As it is unclear what happens there I cannot really rely on GitVersion at the moment.

Your Environment

  • Version Used: 5.6.9+Branch.main.Sha.ecf7f70a3d2fc18be561baeaff4eac1d930f8781 installed by the dotnet CLI
  • Operating System and version (Windows 10, Ubuntu 18.04): Windows 10
  • .NET SDK 5.0.203
  • git 2.23.0.windows.1

mglochsen avatar May 19 '21 16:05 mglochsen

Are you able to reproduce this in a RepositoryFixture test akin to the following and submit it as a pull request?

https://github.com/GitTools/GitVersion/blob/fe2e24b427f224e3b6dd855b77d957a2e04286d3/src/GitVersion.Core.Tests/IntegrationTests/FeatureBranchScenarios.cs#L82-L94

asbjornu avatar May 19 '21 21:05 asbjornu

Hello @asbjornu , I'll try to reproduce the issue in a test today. I'll let you know if I can give you more information.

mglochsen avatar May 20 '21 07:05 mglochsen

I was not able to reproduce the issue within a test. I just found out that problems might be caused be the fast-forward merges that I was using.

Nevertheless I will create a pull request with my unit test. It's in my opinion far to complex for a unit test but I let you decide if you want to add it.

mglochsen avatar May 20 '21 10:05 mglochsen

I was not able to reproduce the issue within a test. I just found out that problems might be caused be the fast-forward merges that I was using.

Yes, fast-forward merges don't play nice with GitVersion.

asbjornu avatar May 20 '21 12:05 asbjornu

I was not able to reproduce the issue within a test. I just found out that problems might be caused be the fast-forward merges that I was using.

Yes, fast-forward merges don't play nice with GitVersion.

Is there anything one could do to make GitVersion work with FF merges? If there would be a strategy I could imagine trying to implement it.

mglochsen avatar May 21 '21 07:05 mglochsen

I suppose we could introduce a new mode for it, but I'm not sure what it should be called or how it should work. Do you have any suggestions?

asbjornu avatar May 21 '21 09:05 asbjornu

I'm not very familiar with the GitVersion internals right now. Are you talking about the versioning mode? I would be interested in using GitVersion with the existing modes, but could also work with FF merges. I'll have a closer look at the sources next week and can then maybe suggest something.

mglochsen avatar May 21 '21 10:05 mglochsen

A mode in GitVersion corresponds to how you use Git. If you don't use Git in one of the recommended ways (Git Flow, GitHub Flow, Mainline, etc.), you can't expect GitVersion to provide you with meaningful version numbers. For GitVersion to support your fast-forward flow, we'd need to introduce a new mode.

asbjornu avatar May 21 '21 10:05 asbjornu

Powershell script to simulate merges fast-forwards, causing GitVersion to not calculate correct semver

del .git -Recurse -Force
git init
$version = "0.1.0"
git checkout -b develop
git commit -am "$version" --allow-empty
git checkout -b release/$version develop
git merge develop 
git checkout -b master release/$version
git merge release/$version 
git commit -am "$version" --allow-empty
gitversion
git checkout develop
git merge master

$version = "0.1.1"
git commit -am "$version" --allow-empty
git checkout -b release/$version develop
git merge develop 
git checkout master
git merge release/$version 
gitversion
git checkout develop

$version = "0.2.0"
git commit -am "$version" --allow-empty
git checkout -b release/$version develop
git merge develop 
git checkout master
git merge release/$version 
gitversion
git checkout develop

$version = "0.2.1"
git commit -am "$version" --allow-empty
git checkout -b release/$version develop
git merge develop 
git checkout master
git merge release/$version 
gitversion
git checkout develop

Updated version, using no-ff

del .git -Recurse -Force
git init
$version = "0.1.0"
git checkout -b develop
git commit -am "$version" --allow-empty
git checkout -b release/$version develop
git merge develop 
git checkout -b master release/$version
git merge release/$version --no-ff
git commit -am "$version" --allow-empty
gitversion
git checkout develop
git merge master

$version = "0.1.1"
git commit -am "$version" --allow-empty
git checkout -b release/$version develop
git merge develop 
git checkout master
git merge release/$version --no-ff
gitversion
git checkout develop

$version = "0.2.0"
git commit -am "$version" --allow-empty
git checkout -b release/$version develop
git merge develop 
git checkout master
git merge release/$version --no-ff
gitversion
git checkout develop

$version = "0.2.1"
git commit -am "$version" --allow-empty
git checkout -b release/$version develop
git merge develop 
git checkout master
git merge release/$version --no-ff
gitversion
git checkout develop

JohanSpannare avatar Jun 10 '21 11:06 JohanSpannare

@JohanSpannare, fast-forward merges messes up version calculation royally, yes. Unless you're using mode: Mainline and trunk-based development, I would strongly recommend against using it.

asbjornu avatar Sep 02 '22 21:09 asbjornu

Actually I don't understand the statement that fast-forward merges messes up version calculation in combination with the behavior generating sporadicly a different version. Of course in some situation using fast-forward merge might be not so good in other they are. The developer or release manager should know in which circumstances which merge strategy is the best choice and ensure the workflow rules. But this discussion has nothing to do with this topic.

I have tested the script multiply times with the current version on main and cannot reproduce it. Thus I'm going to close this issue. If this happened again please re-open this bug or create a new one. Thank you.

BTW: The fallback version strategy has been changed and yields to 0.0.0 should increment true. Maybe it was related to that. Who knows!?

HHobeck avatar Mar 21 '23 06:03 HHobeck