From e8cb4954b6da27feb92ea7a976273caf1766975b Mon Sep 17 00:00:00 2001 From: Frank Genois Date: Tue, 8 Feb 2022 14:09:31 -0500 Subject: [PATCH] Sped up the Normalization by removing an unnecessary O(n^2) loop --- src/GitVersion.Core/Core/GitPreparer.cs | 9 ++++----- src/GitVersion.Core/Git/IReferenceCollection.cs | 1 + src/GitVersion.Core/Git/ReferenceName.cs | 3 +++ src/GitVersion.LibGit2Sharp/Git/ReferenceCollection.cs | 2 ++ 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/GitVersion.Core/Core/GitPreparer.cs b/src/GitVersion.Core/Core/GitPreparer.cs index cef32ddb9a..6c3f51596f 100644 --- a/src/GitVersion.Core/Core/GitPreparer.cs +++ b/src/GitVersion.Core/Core/GitPreparer.cs @@ -314,15 +314,14 @@ private void CreateOrUpdateLocalBranchesFromRemoteTrackingOnes(string remoteName { var remoteTrackingReferenceName = remoteTrackingReference.Name.Canonical; var branchName = remoteTrackingReferenceName.Substring(prefix.Length); - var localCanonicalName = "refs/heads/" + branchName; + var localReferenceName = ReferenceName.FromBranchName(branchName); - var referenceName = ReferenceName.Parse(localCanonicalName); // We do not want to touch our current branch if (this.repository.Head.Name.EquivalentTo(branchName)) continue; - if (this.repository.Refs.Any(x => x.Name.Equals(referenceName))) + if (this.repository.Refs[localReferenceName] is not null) { - var localRef = this.repository.Refs[localCanonicalName]!; + var localRef = this.repository.Refs[localReferenceName]!; if (localRef.TargetIdentifier == remoteTrackingReference.TargetIdentifier) { this.log.Info($"Skipping update of '{remoteTrackingReference.Name.Canonical}' as it already matches the remote ref."); @@ -335,7 +334,7 @@ private void CreateOrUpdateLocalBranchesFromRemoteTrackingOnes(string remoteName } this.log.Info($"Creating local branch from remote tracking '{remoteTrackingReference.Name.Canonical}'."); - this.repository.Refs.Add(localCanonicalName, remoteTrackingReference.TargetIdentifier, true); + this.repository.Refs.Add(localReferenceName.Canonical, remoteTrackingReference.TargetIdentifier, true); var branch = this.repository.Branches[branchName]!; this.repository.Branches.UpdateTrackedBranch(branch, remoteTrackingReferenceName); diff --git a/src/GitVersion.Core/Git/IReferenceCollection.cs b/src/GitVersion.Core/Git/IReferenceCollection.cs index 07d79d8ad7..8d5bde26d2 100644 --- a/src/GitVersion.Core/Git/IReferenceCollection.cs +++ b/src/GitVersion.Core/Git/IReferenceCollection.cs @@ -4,6 +4,7 @@ public interface IReferenceCollection : IEnumerable { IReference? Head { get; } IReference? this[string name] { get; } + IReference? this[ReferenceName referenceName] { get; } void Add(string name, string canonicalRefNameOrObjectish, bool allowOverwrite = false); void UpdateTarget(IReference directRef, IObjectId targetId); IEnumerable FromGlob(string prefix); diff --git a/src/GitVersion.Core/Git/ReferenceName.cs b/src/GitVersion.Core/Git/ReferenceName.cs index 98ae18f44d..4e949e94fa 100644 --- a/src/GitVersion.Core/Git/ReferenceName.cs +++ b/src/GitVersion.Core/Git/ReferenceName.cs @@ -38,6 +38,9 @@ public static ReferenceName Parse(string canonicalName) } throw new ArgumentException($"The {nameof(canonicalName)} is not a Canonical name"); } + + public static ReferenceName FromBranchName(string branchName) => Parse(LocalBranchPrefix + branchName); + public string Canonical { get; } public string Friendly { get; } public string WithoutRemote { get; } diff --git a/src/GitVersion.LibGit2Sharp/Git/ReferenceCollection.cs b/src/GitVersion.LibGit2Sharp/Git/ReferenceCollection.cs index 389e1fadc4..e03480a0a1 100644 --- a/src/GitVersion.LibGit2Sharp/Git/ReferenceCollection.cs +++ b/src/GitVersion.LibGit2Sharp/Git/ReferenceCollection.cs @@ -22,6 +22,8 @@ public IReference? this[string name] } } + public IReference? this[ReferenceName referenceName] => this[referenceName.Canonical]; + public IReference? Head => this["HEAD"]; public IEnumerable FromGlob(string prefix) => this.innerCollection.FromGlob(prefix).Select(reference => new Reference(reference));