Skip to content

Commit c338f48

Browse files
authored
Merge pull request #3585 from AntonMTolmachev/cache-tags-in-increment-strategy-finder
Improve performance on repositories with a lot of tags
2 parents 015a957 + 448de3e commit c338f48

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using GitVersion.Configuration;
2+
using GitVersion.Core.Tests.Helpers;
3+
4+
namespace GitVersion.Core.Tests.IntegrationTests;
5+
6+
public class PerformanceScenarios : TestBase
7+
{
8+
[Test]
9+
public void RepositoryWithALotOfTags()
10+
{
11+
var configuration = GitFlowConfigurationBuilder.New.Build();
12+
13+
using var fixture = new EmptyRepositoryFixture();
14+
15+
const int maxCommits = 500;
16+
for (int i = 0; i < maxCommits; i++)
17+
{
18+
fixture.MakeATaggedCommit($"1.0.{i}");
19+
}
20+
21+
fixture.BranchTo("feature");
22+
fixture.MakeACommit();
23+
24+
var sw = Stopwatch.StartNew();
25+
26+
fixture.AssertFullSemver($"1.0.{maxCommits}-feature.1+1", configuration);
27+
sw.ElapsedMilliseconds.ShouldBeLessThan(5000);
28+
}
29+
}

src/GitVersion.Core/VersionCalculation/IncrementStrategyFinder.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ internal class IncrementStrategyFinder : IIncrementStrategyFinder
1616
private readonly Dictionary<string, VersionField?> commitIncrementCache = new();
1717
private readonly Dictionary<string, Dictionary<string, int>> headCommitsMapCache = new();
1818
private readonly Dictionary<string, ICommit[]> headCommitsCache = new();
19+
private readonly Lazy<IReadOnlySet<string?>> tagsShaCache;
1920

2021
private static readonly Regex DefaultMajorPatternRegex = new(DefaultMajorPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
2122
private static readonly Regex DefaultMinorPatternRegex = new(DefaultMinorPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
@@ -24,7 +25,11 @@ internal class IncrementStrategyFinder : IIncrementStrategyFinder
2425

2526
private readonly IGitRepository repository;
2627

27-
public IncrementStrategyFinder(IGitRepository repository) => this.repository = repository.NotNull();
28+
public IncrementStrategyFinder(IGitRepository repository)
29+
{
30+
this.repository = repository.NotNull();
31+
this.tagsShaCache = new Lazy<IReadOnlySet<string?>>(ReadRepositoryTagsSha);
32+
}
2833

2934
public VersionField DetermineIncrementedField(ICommit? currentCommit, BaseVersion baseVersion, EffectiveConfiguration configuration)
3035
{
@@ -79,12 +84,10 @@ public VersionField DetermineIncrementedField(ICommit? currentCommit, BaseVersio
7984
}
8085

8186
var commits = GetIntermediateCommits(baseCommit, currentCommit);
82-
8387
// consider commit messages since latest tag only (see #3071)
84-
var tags = new HashSet<string?>(repository.Tags.Select(t => t.TargetSha));
8588
commits = commits
8689
.Reverse()
87-
.TakeWhile(x => !tags.Contains(x.Sha))
90+
.TakeWhile(x => !this.tagsShaCache.Value.Contains(x.Sha))
8891
.Reverse();
8992

9093
if (configuration.CommitMessageIncrementing == CommitMessageIncrementMode.MergeMessageOnly)
@@ -101,6 +104,8 @@ public VersionField DetermineIncrementedField(ICommit? currentCommit, BaseVersio
101104
);
102105
}
103106

107+
private IReadOnlySet<string?> ReadRepositoryTagsSha() => repository.Tags.Select(t => t.TargetSha).ToHashSet();
108+
104109
private static Regex TryGetRegexOrDefault(string? messageRegex, Regex defaultRegex) =>
105110
messageRegex == null
106111
? defaultRegex

0 commit comments

Comments
 (0)