diff --git a/src/GitVersion.Core.Tests/IntegrationTests/DevelopScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/DevelopScenarios.cs index bd9f36b2a4..b63e2e43a7 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/DevelopScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/DevelopScenarios.cs @@ -228,11 +228,11 @@ public void CommitsSinceVersionSourceShouldNotGoDownUponGitFlowReleaseFinish() fixture.Checkout("develop"); fixture.MergeNoFF("release/1.2.0"); fixture.MakeACommit("commit in develop - 6"); - fixture.AssertFullSemver("1.3.0-alpha.9"); + fixture.AssertFullSemver("1.3.0-alpha.6"); fixture.SequenceDiagram.Destroy("release/1.2.0"); fixture.Repository.Branches.Remove("release/1.2.0"); - const string expectedFullSemVer = "1.3.0-alpha.9"; + const string expectedFullSemVer = "1.3.0-alpha.6"; fixture.AssertFullSemver(expectedFullSemVer, config); } @@ -260,11 +260,11 @@ public void CommitsSinceVersionSourceShouldNotGoDownUponMergingFeatureOnlyToDeve fixture.MakeACommit("commit in develop - 2"); fixture.AssertFullSemver("1.3.0-alpha.1"); fixture.MergeNoFF("release/1.2.0"); - fixture.AssertFullSemver("1.3.0-alpha.5"); + fixture.AssertFullSemver("1.3.0-alpha.2"); fixture.SequenceDiagram.Destroy("release/1.2.0"); fixture.Repository.Branches.Remove("release/1.2.0"); - const string expectedFullSemVer = "1.3.0-alpha.5"; + const string expectedFullSemVer = "1.3.0-alpha.2"; fixture.AssertFullSemver(expectedFullSemVer, config); } @@ -317,16 +317,16 @@ public void WhenPreventIncrementOfMergedBranchVersionIsSetToFalseForDevelopCommi fixture.MergeNoFF(ReleaseBranch); // Version numbers will still be correct when the release branch is around. - fixture.AssertFullSemver("1.2.0-alpha.6"); - fixture.AssertFullSemver("1.2.0-alpha.6", config); + fixture.AssertFullSemver("1.2.0-alpha.3"); + fixture.AssertFullSemver("1.2.0-alpha.3", config); var versionSourceBeforeReleaseBranchIsRemoved = fixture.GetVersion(config).Sha; fixture.Repository.Branches.Remove(ReleaseBranch); var versionSourceAfterReleaseBranchIsRemoved = fixture.GetVersion(config).Sha; Assert.AreEqual(versionSourceBeforeReleaseBranchIsRemoved, versionSourceAfterReleaseBranchIsRemoved); - fixture.AssertFullSemver("1.2.0-alpha.6"); - fixture.AssertFullSemver("1.2.0-alpha.6", config); + fixture.AssertFullSemver("1.2.0-alpha.3"); + fixture.AssertFullSemver("1.2.0-alpha.3", config); config.Branches = new Dictionary { @@ -374,7 +374,7 @@ public void WhenPreventIncrementOfMergedBranchVersionIsSetToFalseForDevelopCommi fixture.Repository.MakeCommits(2); fixture.MergeNoFF(ReleaseBranch); fixture.Repository.Branches.Remove(ReleaseBranch); - fixture.AssertFullSemver("1.2.0-alpha.6", config); + fixture.AssertFullSemver("1.2.0-alpha.3", config); // Create hotfix for defects found in release/1.1.0 const string HotfixBranch = "hotfix/1.1.1"; @@ -391,11 +391,11 @@ public void WhenPreventIncrementOfMergedBranchVersionIsSetToFalseForDevelopCommi fixture.Checkout("develop"); // Simulate some work done on develop while the hotfix branch was open. fixture.Repository.MakeCommits(3); - fixture.AssertFullSemver("1.2.0-alpha.9", config); + fixture.AssertFullSemver("1.2.0-alpha.6", config); fixture.Repository.MergeNoFF(HotfixBranch); - fixture.AssertFullSemver("1.2.0-alpha.19", config); + fixture.AssertFullSemver("1.2.0-alpha.10", config); fixture.Repository.Branches.Remove(HotfixBranch); - fixture.AssertFullSemver("1.2.0-alpha.19", config); + fixture.AssertFullSemver("1.2.0-alpha.10", config); } } diff --git a/src/GitVersion.Core.Tests/IntegrationTests/DocumentationSamples.cs b/src/GitVersion.Core.Tests/IntegrationTests/DocumentationSamples.cs index 5b1d12634a..2de00f5b6d 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/DocumentationSamples.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/DocumentationSamples.cs @@ -155,7 +155,7 @@ public void GitFlowMinorRelease() // Not 0 for commit count as we can't know the increment rules of the merged branch fixture.Checkout("develop"); - fixture.AssertFullSemver("1.4.0-alpha.4"); + fixture.AssertFullSemver("1.4.0-alpha.2"); Console.WriteLine(fixture.SequenceDiagram.GetDiagram()); } @@ -211,7 +211,7 @@ public void GitFlowMajorRelease() // Not 0 for commit count as we can't know the increment rules of the merged branch fixture.Checkout("develop"); - fixture.AssertFullSemver("2.1.0-alpha.4"); + fixture.AssertFullSemver("2.1.0-alpha.2"); Console.WriteLine(fixture.SequenceDiagram.GetDiagram()); } diff --git a/src/GitVersion.Core.Tests/IntegrationTests/GitflowScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/GitflowScenarios.cs index 630400c766..4c887a994b 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/GitflowScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/GitflowScenarios.cs @@ -41,16 +41,16 @@ public void GitflowComplexExample() fixture.Checkout(developBranch); fixture.MergeNoFF(release1Branch); fixture.Repository.Branches.Remove(fixture.Repository.Branches[release1Branch]); - fixture.AssertFullSemver("1.2.0-alpha.2"); + fixture.AssertFullSemver("1.2.0-alpha.1"); // Feature 2 fixture.BranchTo(feature2Branch); fixture.MakeACommit("added feature 2"); - fixture.AssertFullSemver("1.2.0-f2.1+3"); + fixture.AssertFullSemver("1.2.0-f2.1+2"); fixture.Checkout(developBranch); fixture.MergeNoFF(feature2Branch); fixture.Repository.Branches.Remove(fixture.Repository.Branches[feature2Branch]); - fixture.AssertFullSemver("1.2.0-alpha.4"); + fixture.AssertFullSemver("1.2.0-alpha.3"); // Release 1.2.0 fixture.BranchTo(release2Branch); @@ -64,13 +64,13 @@ public void GitflowComplexExample() fixture.Checkout(developBranch); fixture.MergeNoFF(release2Branch); fixture.Repository.Branches.Remove(fixture.Repository.Branches[release2Branch]); - fixture.AssertFullSemver("1.3.0-alpha.2"); + fixture.AssertFullSemver("1.3.0-alpha.1"); // Hotfix fixture.Checkout(MainBranch); fixture.BranchTo(hotfixBranch); fixture.MakeACommit("added hotfix"); - fixture.AssertFullSemver("1.2.1-beta.1+7"); + fixture.AssertFullSemver("1.2.1-beta.1+1"); fixture.Checkout(MainBranch); fixture.MergeNoFF(hotfixBranch); fixture.AssertFullSemver("1.2.1+2"); @@ -79,7 +79,7 @@ public void GitflowComplexExample() fixture.Checkout(developBranch); fixture.MergeNoFF(hotfixBranch); fixture.Repository.Branches.Remove(fixture.Repository.Branches[hotfixBranch]); - fixture.AssertFullSemver("1.3.0-alpha.9"); + fixture.AssertFullSemver("1.3.0-alpha.3"); } } } diff --git a/src/GitVersion.Core.Tests/IntegrationTests/ReleaseBranchScenarios.cs b/src/GitVersion.Core.Tests/IntegrationTests/ReleaseBranchScenarios.cs index 0fd75f14a8..a54c2ec216 100644 --- a/src/GitVersion.Core.Tests/IntegrationTests/ReleaseBranchScenarios.cs +++ b/src/GitVersion.Core.Tests/IntegrationTests/ReleaseBranchScenarios.cs @@ -48,12 +48,12 @@ public void NoMergeBacksToDevelopInCaseThereAreChangesInReleaseBranch() // Merge to develop fixture.Checkout("develop"); fixture.Repository.MergeNoFF("release/1.0.0"); - fixture.AssertFullSemver("1.1.0-alpha.2"); + fixture.AssertFullSemver("1.1.0-alpha.1"); fixture.Repository.MakeACommit(); fixture.Repository.Branches.Remove("release/1.0.0"); - fixture.AssertFullSemver("1.1.0-alpha.3"); + fixture.AssertFullSemver("1.1.0-alpha.2"); } [Test] @@ -184,7 +184,7 @@ public void WhenReleaseBranchOffMainIsMergedIntoMainVersionIsTakenWithIt() } [Test] - public void MainVersioningContinuousCorrectlyAfterMergingReleaseBranch() + public void MainVersioningContinuesCorrectlyAfterMergingReleaseBranch() { using var fixture = new EmptyRepositoryFixture(); fixture.Repository.MakeATaggedCommit("1.0.3"); @@ -201,6 +201,30 @@ public void MainVersioningContinuousCorrectlyAfterMergingReleaseBranch() fixture.AssertFullSemver("2.0.1+1"); } + [Test] + public void MainVersioningContinuesCountingAfterMergingTheSameReleaseBranchMultipleTimes() + { + using var fixture = new EmptyRepositoryFixture(); + fixture.Repository.MakeATaggedCommit("1.0.3"); + fixture.Repository.MakeCommits(1); + fixture.Repository.CreateBranch("release/2.0.0"); + fixture.Checkout("release/2.0.0"); + fixture.Repository.MakeCommits(4); + fixture.Checkout(MainBranch); + fixture.Repository.MergeNoFF("release/2.0.0", Generate.SignatureNow()); + + fixture.AssertFullSemver("2.0.0+0"); + + fixture.Checkout("release/2.0.0"); + fixture.Repository.MakeCommits(3); + fixture.Checkout(MainBranch); + fixture.Repository.MergeNoFF("release/2.0.0", Generate.SignatureNow()); + + fixture.AssertFullSemver("2.0.0+4"); + fixture.Repository.MakeCommits(1); + fixture.AssertFullSemver("2.0.0+5"); + } + [Test] public void WhenReleaseBranchIsMergedIntoDevelopHighestVersionIsTakenWithIt() { @@ -434,7 +458,7 @@ public void CommitOnDevelopAfterReleaseBranchMergeToDevelopShouldNotResetCount() } [Test] - public void CommitBeetweenMergeReleaseToDevelopShouldNotResetCount() + public void CommitBetweenMergeReleaseToDevelopShouldNotResetCount() { var config = new Config { diff --git a/src/GitVersion.Core/VersionCalculation/BaseVersionCalculator.cs b/src/GitVersion.Core/VersionCalculation/BaseVersionCalculator.cs index 62542bad17..8a4838ff25 100644 --- a/src/GitVersion.Core/VersionCalculation/BaseVersionCalculator.cs +++ b/src/GitVersion.Core/VersionCalculation/BaseVersionCalculator.cs @@ -53,24 +53,53 @@ public BaseVersion GetBaseVersion() if (matchingVersionsOnceIncremented.Any()) { - static Versions CompareVersions(Versions versions1, Versions version2) + if (matchingVersionsOnceIncremented.Count > 1) { - if (versions1.Version.BaseVersionSource == null) + static Versions CompareVersions(Versions versions1, Versions version2) { - return version2; + if (versions1.Version.BaseVersionSource == null) + { + return version2; + } + if (version2.Version.BaseVersionSource == null) + { + return versions1; + } + + return versions1.Version.BaseVersionSource.When < version2.Version.BaseVersionSource.When ? versions1 : version2; } - if (version2.Version.BaseVersionSource == null) + + log.Info($"Found multiple base versions which will produce the same SemVer ({maxVersion.IncrementedVersion})"); + log.Info($"Here are the different source candidate for commit counting : "); + foreach (var baseVersion in matchingVersionsOnceIncremented.Select(b => b.Version)) { - return versions1; + if (baseVersion != null) + { + log.Info($" - {BaseVersionToString(baseVersion)}"); + } } - return versions1.Version.BaseVersionSource.When < version2.Version.BaseVersionSource.When ? versions1 : version2; - } + var tagVersions = matchingVersionsOnceIncremented.FindAll(b => b.Version.Source.Contains("Git tag")); + + if (tagVersions.Count > 0) + { + log.Info("As there are Git tags, the other sources will be discarded"); + matchingVersionsOnceIncremented = tagVersions; + } - var oldest = matchingVersionsOnceIncremented.Aggregate(CompareVersions); - baseVersionWithOldestSource = oldest.Version; - maxVersion = oldest; - this.log.Info($"Found multiple base versions which will produce the same SemVer ({maxVersion.IncrementedVersion}), taking oldest source for commit counting ({baseVersionWithOldestSource.Source})"); + maxVersion = matchingVersionsOnceIncremented.Aggregate(CompareVersions); + baseVersionWithOldestSource = maxVersion.Version; + log.Info($"Taking oldest source for commit counting : {BaseVersionToString(baseVersionWithOldestSource)}"); + } + else + { + maxVersion = matchingVersionsOnceIncremented.First(); + baseVersionWithOldestSource = maxVersion.Version; + log.Info( + $"Found a base versions which will produce the following SemVer ({maxVersion.IncrementedVersion}), " + + $"with the following source for commit counting : {BaseVersionToString(baseVersionWithOldestSource)}" + ); + } } else { @@ -92,11 +121,15 @@ static Versions CompareVersions(Versions versions1, Versions version2) baseVersionWithOldestSource.BaseVersionSource, maxVersion.Version.BranchNameOverride); - this.log.Info($"Base version used: {calculatedBase}"); + log.Info($"Base version used: {calculatedBase}"); return calculatedBase; } } + + private static string BaseVersionToString(BaseVersion baseVersion) => + $"{baseVersion!.Source} ({baseVersion!.BaseVersionSource!.Sha})"; + private IEnumerable GetBaseVersions(IVersionStrategy strategy) { foreach (var version in strategy.GetVersions())