diff --git a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MainlineVersionStrategy.cs b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MainlineVersionStrategy.cs index a7cd9a342d..805dfae9f8 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MainlineVersionStrategy.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MainlineVersionStrategy.cs @@ -21,6 +21,7 @@ internal sealed class MainlineVersionStrategy( private readonly ITaggedSemanticVersionService taggedSemanticVersionService = taggedSemanticVersionService.NotNull(); private readonly IRepositoryStore repositoryStore = repositoryStore.NotNull(); private readonly IIncrementStrategyFinder incrementStrategyFinder = incrementStrategyFinder.NotNull(); + private readonly Dictionary>> commitsWasBranchedFromCache = new(); private GitVersionContext Context => contextLazy.Value; @@ -277,6 +278,15 @@ private bool IterateOverCommitsRecursive( private Dictionary> GetCommitsWasBranchedFrom( IBranch branch, params IBranch[] excludedBranches) { + // Create cache key from canonical branch name and canonical excluded branch names + var cacheKey = $"{branch.Name.Canonical}|{string.Join(",", excludedBranches.Select(b => b.Name.Canonical).OrderBy(n => n))}"; + + // Return cached result if available + if (this.commitsWasBranchedFromCache.TryGetValue(cacheKey, out var cachedResult)) + { + return cachedResult; + } + Dictionary> result = []; var branchCommits = repositoryStore.FindCommitBranchesBranchedFrom( @@ -298,8 +308,9 @@ private bool IterateOverCommitsRecursive( throw new InvalidOperationException(); } - if ((branchConfiguration.IsMainBranch ?? Context.Configuration.IsMainBranch) != true) continue; - foreach (var _ in value.ToArray()) + // Fix: Just add the item once instead of duplicating for each existing item + // The original logic caused exponential growth: 1→2→4→8→16 with multiple branches + if ((branchConfiguration.IsMainBranch ?? Context.Configuration.IsMainBranch).GetValueOrDefault()) { value.Add(new(item, branchConfiguration)); } @@ -315,6 +326,10 @@ private bool IterateOverCommitsRecursive( { result[item.Key] = [.. item.Value.OrderByDescending(element => (element.Configuration.IsMainBranch ?? Context.Configuration.IsMainBranch) == true)]; } + + // Cache the result for future calls + this.commitsWasBranchedFromCache[cacheKey] = result; + return result; }