From 5b0125b49ceedda02e67896f87aae21802dd18ad Mon Sep 17 00:00:00 2001 From: Fenikkusu Date: Sun, 20 Jul 2025 01:12:03 -0400 Subject: [PATCH] Adding Merge Commit Version Strategy --- .../Configuration/ConfigurationConstants.cs | 3 +- src/GitVersion.Core/PublicAPI.Shipped.txt | 1 + .../MergeCommitVersionStrategy.cs | 97 +++++++++++++++++++ .../VersionCalculation/VersionStrategies.cs | 3 +- 4 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MergeCommitVersionStrategy.cs diff --git a/src/GitVersion.Core/Configuration/ConfigurationConstants.cs b/src/GitVersion.Core/Configuration/ConfigurationConstants.cs index 017990354d..3f18e73c14 100644 --- a/src/GitVersion.Core/Configuration/ConfigurationConstants.cs +++ b/src/GitVersion.Core/Configuration/ConfigurationConstants.cs @@ -19,7 +19,8 @@ internal static class ConfigurationConstants VersionStrategies.MergeMessage, VersionStrategies.TaggedCommit, VersionStrategies.TrackReleaseBranches, - VersionStrategies.VersionInBranchName + VersionStrategies.VersionInBranchName, + VersionStrategies.MergeCommit ]; public const string DefaultAssemblyInformationalFormat = "{InformationalVersion}"; public const string DefaultCommitDateFormat = "yyyy-MM-dd"; diff --git a/src/GitVersion.Core/PublicAPI.Shipped.txt b/src/GitVersion.Core/PublicAPI.Shipped.txt index 2b3133a9e8..28bfc6f33f 100644 --- a/src/GitVersion.Core/PublicAPI.Shipped.txt +++ b/src/GitVersion.Core/PublicAPI.Shipped.txt @@ -680,6 +680,7 @@ GitVersion.VersionCalculation.VersionStrategies GitVersion.VersionCalculation.VersionStrategies.ConfiguredNextVersion = 2 -> GitVersion.VersionCalculation.VersionStrategies GitVersion.VersionCalculation.VersionStrategies.Fallback = 1 -> GitVersion.VersionCalculation.VersionStrategies GitVersion.VersionCalculation.VersionStrategies.Mainline = 64 -> GitVersion.VersionCalculation.VersionStrategies +GitVersion.VersionCalculation.VersionStrategies.MergeCommit = 128 -> GitVersion.VersionCalculation.VersionStrategies GitVersion.VersionCalculation.VersionStrategies.MergeMessage = 4 -> GitVersion.VersionCalculation.VersionStrategies GitVersion.VersionCalculation.VersionStrategies.None = 0 -> GitVersion.VersionCalculation.VersionStrategies GitVersion.VersionCalculation.VersionStrategies.TaggedCommit = 8 -> GitVersion.VersionCalculation.VersionStrategies diff --git a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MergeCommitVersionStrategy.cs b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MergeCommitVersionStrategy.cs new file mode 100644 index 0000000000..180f92b619 --- /dev/null +++ b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MergeCommitVersionStrategy.cs @@ -0,0 +1,97 @@ +using GitVersion.Common; +using GitVersion.Configuration; +using GitVersion.Core; +using GitVersion.Extensions; +using GitVersion.Git; +using GitVersion.Logging; + +namespace GitVersion.VersionCalculation; + +/// +/// Version is extracted from older merge commits. +/// BaseVersionSource is the commit where the message was found. +/// +internal sealed class MergeCommitVersionStrategy(ILog log, Lazy contextLazy, + IRepositoryStore repositoryStore, IIncrementStrategyFinder incrementStrategyFinder, IEffectiveBranchConfigurationFinder effectiveBranchConfigurationFinder, + ITaggedSemanticVersionRepository taggedSemanticVersionRepository + ) + : IVersionStrategy +{ + private readonly ILog log = log.NotNull(); + private readonly Lazy contextLazy = contextLazy.NotNull(); + private readonly IRepositoryStore repositoryStore = repositoryStore.NotNull(); + private readonly IIncrementStrategyFinder incrementStrategyFinder = incrementStrategyFinder.NotNull(); + private readonly IEffectiveBranchConfigurationFinder effectiveBranchConfigurationFinder = effectiveBranchConfigurationFinder.NotNull(); + private readonly ITaggedSemanticVersionRepository taggedSemanticVersionRepository = taggedSemanticVersionRepository.NotNull(); + + private GitVersionContext Context => contextLazy.Value; + + public IEnumerable GetBaseVersions(EffectiveBranchConfiguration configuration) + { + configuration.NotNull(); + + if (!Context.Configuration.VersionStrategy.HasFlag(VersionStrategies.MergeCommit)) + { + yield break; + } + + var taggedCommits = this.taggedSemanticVersionRepository.GetTaggedSemanticVersions( + tagPrefix: Context.Configuration.TagPrefixPattern, + format: Context.Configuration.SemanticVersionFormat, + ignore: Context.Configuration.Ignore + ); + var previousVersion = new SemanticVersion(0, 0, 0); + + // Must Loop In Reverse To Ensure Correct Version Calculation + foreach (var commit in configuration.Value.Ignore.Filter(Context.CurrentBranchCommits.ToArray()).Reverse()) + { + if (taggedCommits.Contains(commit)) + { + this.log.Debug($"Found tagged commit {commit}, adjusting previous version."); + previousVersion = taggedCommits[commit].First().Value; + } + if (!commit.IsMergeCommit()) + { + continue; + } + + // Using Merge Message Since The Formats Are Identical + if (!MergeMessage.TryParse(commit, Context.Configuration, out var mergeMessage)) + { + continue; + } + + this.log.Info($"Found commit [{commit}] matching merge message format: {mergeMessage.FormatName}"); + + var currentBranch = this.repositoryStore.GetTargetBranch(mergeMessage.MergedBranch!.Friendly); + var branchConfiguration = this.effectiveBranchConfigurationFinder.GetConfigurations(currentBranch, Context.Configuration).First(); + var baseVersionSource = this.repositoryStore.FindMergeBase(commit.Parents[0], commit.Parents[1]); + + var label = branchConfiguration.Value.GetBranchSpecificLabel(mergeMessage.MergedBranch!.Friendly, ""); + var increment = this.incrementStrategyFinder.DetermineIncrementedField( + currentCommit: commit, + baseVersionSource: baseVersionSource, + shouldIncrement: true, + configuration: branchConfiguration.Value, + label: label + ); + + yield return new BaseVersion($"Merge Commit From '{mergeMessage.MergedBranch?.Friendly}'", previousVersion + ) + { + Operator = new() + { + Increment = increment, + ForceIncrement = false, + Label = label + } + }; + + previousVersion = previousVersion.Increment( + increment, + label, + true + ); + } + } +} diff --git a/src/GitVersion.Core/VersionCalculation/VersionStrategies.cs b/src/GitVersion.Core/VersionCalculation/VersionStrategies.cs index 4fe020c87a..fd5621c9af 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionStrategies.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionStrategies.cs @@ -10,5 +10,6 @@ public enum VersionStrategies TaggedCommit = 8, TrackReleaseBranches = 16, VersionInBranchName = 32, - Mainline = 64 + Mainline = 64, + MergeCommit = 128 }