Skip to content

Commit

Permalink
Merge pull request #3585 from AntonMTolmachev/cache-tags-in-increment…
Browse files Browse the repository at this point in the history
…-strategy-finder

Improve performance on repositories with a lot of tags
  • Loading branch information
arturcic authored Jun 10, 2023
2 parents 015a957 + 448de3e commit c338f48
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
29 changes: 29 additions & 0 deletions src/GitVersion.Core.Tests/IntegrationTests/PerformanceScenarios.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using GitVersion.Configuration;
using GitVersion.Core.Tests.Helpers;

namespace GitVersion.Core.Tests.IntegrationTests;

public class PerformanceScenarios : TestBase
{
[Test]
public void RepositoryWithALotOfTags()
{
var configuration = GitFlowConfigurationBuilder.New.Build();

using var fixture = new EmptyRepositoryFixture();

const int maxCommits = 500;
for (int i = 0; i < maxCommits; i++)
{
fixture.MakeATaggedCommit($"1.0.{i}");
}

fixture.BranchTo("feature");
fixture.MakeACommit();

var sw = Stopwatch.StartNew();

fixture.AssertFullSemver($"1.0.{maxCommits}-feature.1+1", configuration);
sw.ElapsedMilliseconds.ShouldBeLessThan(5000);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ internal class IncrementStrategyFinder : IIncrementStrategyFinder
private readonly Dictionary<string, VersionField?> commitIncrementCache = new();
private readonly Dictionary<string, Dictionary<string, int>> headCommitsMapCache = new();
private readonly Dictionary<string, ICommit[]> headCommitsCache = new();
private readonly Lazy<IReadOnlySet<string?>> tagsShaCache;

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

private readonly IGitRepository repository;

public IncrementStrategyFinder(IGitRepository repository) => this.repository = repository.NotNull();
public IncrementStrategyFinder(IGitRepository repository)
{
this.repository = repository.NotNull();
this.tagsShaCache = new Lazy<IReadOnlySet<string?>>(ReadRepositoryTagsSha);
}

public VersionField DetermineIncrementedField(ICommit? currentCommit, BaseVersion baseVersion, EffectiveConfiguration configuration)
{
Expand Down Expand Up @@ -79,12 +84,10 @@ public VersionField DetermineIncrementedField(ICommit? currentCommit, BaseVersio
}

var commits = GetIntermediateCommits(baseCommit, currentCommit);

// consider commit messages since latest tag only (see #3071)
var tags = new HashSet<string?>(repository.Tags.Select(t => t.TargetSha));
commits = commits
.Reverse()
.TakeWhile(x => !tags.Contains(x.Sha))
.TakeWhile(x => !this.tagsShaCache.Value.Contains(x.Sha))
.Reverse();

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

private IReadOnlySet<string?> ReadRepositoryTagsSha() => repository.Tags.Select(t => t.TargetSha).ToHashSet();

private static Regex TryGetRegexOrDefault(string? messageRegex, Regex defaultRegex) =>
messageRegex == null
? defaultRegex
Expand Down

0 comments on commit c338f48

Please sign in to comment.