diff --git a/src/GitVersionCore.Tests/Mocks/MockRepository.cs b/src/GitVersionCore.Tests/Mocks/MockRepository.cs index add8bf1684..965cdb93bd 100644 --- a/src/GitVersionCore.Tests/Mocks/MockRepository.cs +++ b/src/GitVersionCore.Tests/Mocks/MockRepository.cs @@ -211,7 +211,7 @@ public void RevParse(string revision, out Reference reference, out GitObject obj public Branch Head { get; set; } public LibGit2Sharp.Configuration Config { get; set; } - public Index Index { get; set; } + public LibGit2Sharp.Index Index { get; set; } public ReferenceCollection Refs { get; set; } public IQueryableCommitLog Commits diff --git a/src/GitVersionCore/IncrementStrategyFinder.cs b/src/GitVersionCore/IncrementStrategyFinder.cs index c4c75e18a8..2d58b70add 100644 --- a/src/GitVersionCore/IncrementStrategyFinder.cs +++ b/src/GitVersionCore/IncrementStrategyFinder.cs @@ -69,13 +69,16 @@ public static class IncrementStrategyFinder public static VersionField? GetIncrementForCommits(GitVersionContext context, IEnumerable commits) { - var majorRegex = CreateRegex(context.Configuration.MajorVersionBumpMessage ?? DefaultMajorPattern); - var minorRegex = CreateRegex(context.Configuration.MinorVersionBumpMessage ?? DefaultMinorPattern); - var patchRegex = CreateRegex(context.Configuration.PatchVersionBumpMessage ?? DefaultPatchPattern); - var none = CreateRegex(context.Configuration.NoBumpMessage ?? DefaultNoBumpPattern); + // More efficient use of Regexes. The static version of Regex.IsMatch caches the compiled regexes. + // see: https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices#static-regular-expressions + + var majorRegex = context.Configuration.MajorVersionBumpMessage ?? DefaultMajorPattern; + var minorRegex = context.Configuration.MinorVersionBumpMessage ?? DefaultMinorPattern; + var patchRegex = context.Configuration.PatchVersionBumpMessage ?? DefaultPatchPattern; + var none = context.Configuration.NoBumpMessage ?? DefaultNoBumpPattern; var increments = commits - .Select(c => FindIncrementFromMessage(c.Message, majorRegex, minorRegex, patchRegex, none)) + .Select(c => GetIncrementFromMessage(c.Message, majorRegex, minorRegex, patchRegex, none)) .Where(v => v != null) .Select(v => v.Value) .ToList(); @@ -88,6 +91,8 @@ public static class IncrementStrategyFinder return null; } + + private static IEnumerable GetIntermediateCommits(IRepository repo, Commit baseCommit, Commit headCommit) { if (baseCommit == null) yield break; @@ -114,21 +119,43 @@ private static IEnumerable GetIntermediateCommits(IRepository repo, Comm } } - private static VersionField? FindIncrementFromMessage(string message, Regex major, Regex minor, Regex patch, Regex none) + private static VersionField? GetIncrementFromMessage(string message, string majorRegex, string minorRegex, string patchRegex, string none) { - if (major.IsMatch(message)) return VersionField.Major; - if (minor.IsMatch(message)) return VersionField.Minor; - if (patch.IsMatch(message)) return VersionField.Patch; - if (none.IsMatch(message)) return VersionField.None; + var key = message.GetHashCode(); + + if (!VersionFieldCache.TryGetValue(key, out var version)) + { + version = FindIncrementFromMessage(message, majorRegex, minorRegex, patchRegex, none); + VersionFieldCache[key] = version; + } + return version; + } + + private static VersionField? FindIncrementFromMessage(string message, string majorRegex, string minorRegex, string patchRegex, string noneRegex) + { + if(IsMatch(message, majorRegex)) return VersionField.Major; + if(IsMatch(message, minorRegex)) return VersionField.Minor; + if(IsMatch(message, patchRegex)) return VersionField.Patch; + if(IsMatch(message, noneRegex)) return VersionField.None; return null; } - private static Regex CreateRegex(string pattern) + private static bool IsMatch(string message, string regex) { - return new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase); + var key = message.GetHashCode() ^ regex.GetHashCode(); + + if (!MatchCache.TryGetValue(key, out var match)) + { + match = Regex.IsMatch(message, regex, RegexOptions.IgnoreCase); + MatchCache[key] = match; + } + return match; } + private static IDictionary MatchCache = new Dictionary(); + private static IDictionary VersionFieldCache = new Dictionary(); + public static VersionField FindDefaultIncrementForBranch( GitVersionContext context, string branch = null ) { var config = context.FullConfiguration.GetConfigForBranch(branch ?? context.CurrentBranch.NameWithoutRemote()); diff --git a/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/BaseVersion.cs b/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/BaseVersion.cs index 72739762c0..02b204da5c 100644 --- a/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/BaseVersion.cs +++ b/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/BaseVersion.cs @@ -31,4 +31,4 @@ public override string ToString() return $"{Source}: {SemanticVersion.ToString("f")} with commit count source {(BaseVersionSource == null ? "External Source" : BaseVersionSource.Sha)} (Incremented: {(ShouldIncrement ? BaseVersionCalculator.MaybeIncrement(_context, this).ToString("t") : "None")})"; } } -} \ No newline at end of file +}