diff --git a/global.json b/global.json index dfbf12676d..6e31df06a5 100644 --- a/global.json +++ b/global.json @@ -5,6 +5,6 @@ "src" ], "sdk": { - "version": "9.0.203" + "version": "9.0.300" } } diff --git a/src/GitVersion.App/GitVersion.App.csproj b/src/GitVersion.App/GitVersion.App.csproj index b3168be34e..7b4fc9b598 100644 --- a/src/GitVersion.App/GitVersion.App.csproj +++ b/src/GitVersion.App/GitVersion.App.csproj @@ -6,6 +6,8 @@ gitversion AnyCPU MIT + true + net8.0;net9.0 diff --git a/src/GitVersion.Core/Core/RepositoryStore.cs b/src/GitVersion.Core/Core/RepositoryStore.cs index ee018444fb..71ee2310a4 100644 --- a/src/GitVersion.Core/Core/RepositoryStore.cs +++ b/src/GitVersion.Core/Core/RepositoryStore.cs @@ -116,52 +116,67 @@ public IEnumerable GetSourceBranches( var commitBranches = FindCommitBranchesBranchedFrom(branch, configuration, excludedBranches).ToHashSet(); var ignore = new HashSet(); - foreach (var commitBranch in commitBranches) + using (this.log.IndentLog($"Finding ignore branches")) { - foreach (var commit in branch.Commits.Where(element => element.When > commitBranch.Commit.When)) + foreach (var commitBranch in commitBranches) { - var parents = commit.Parents.ToArray(); - if (parents.Length > 1 && parents.Any(element => element.Equals(commitBranch.Commit))) + foreach (var commit in branch.Commits.Where(element => element.When > commitBranch.Commit.When)) { - ignore.Add(commitBranch); + var parents = commit.Parents.ToArray(); + if (parents.Length > 1 && parents.Any(element => element.Equals(commitBranch.Commit))) + { + ignore.Add(commitBranch); + } } } } - foreach (var item in commitBranches.Skip(1).Reverse()) + using (this.log.IndentLog($"Filtering out branches")) { - if (ignore.Contains(item)) continue; + IEnumerable commitBranchesReversed = new List(); + using (this.log.IndentLog($"Reverse commit branches")) + { + commitBranchesReversed = commitBranches.Skip(1).Reverse(); + } - foreach (var commitBranch in commitBranches) + foreach (var item in commitBranchesReversed) { - if (item.Commit.Equals(commitBranch.Commit)) break; + if (ignore.Contains(item)) continue; - foreach (var commit in commitBranch.Branch.Commits.Where(element => element.When >= item.Commit.When)) + foreach (var commitBranch in commitBranches) { - if (commit.Equals(item.Commit)) + if (item.Commit.Equals(commitBranch.Commit)) break; + + foreach (var commit in commitBranch.Branch.Commits.Where(element => element.When >= item.Commit.When)) { - commitBranches.Remove(item); + if (commit.Equals(item.Commit)) + { + commitBranches.Remove(item); + } } } } } - foreach (var branchGrouping in commitBranches.GroupBy(element => element.Commit, element => element.Branch)) + using (this.log.IndentLog($"Iterate grouped branches by commit")) { - var referenceMatchFound = false; - var referenceNames = referenceLookup[branchGrouping.Key.Sha].Select(element => element.Name).ToHashSet(); - - foreach (var item in branchGrouping) + foreach (var branchGrouping in commitBranches.GroupBy(element => element.Commit, element => element.Branch)) { - if (!referenceNames.Contains(item.Name)) continue; - if (returnedBranches.Add(item)) yield return item; - referenceMatchFound = true; - } + var referenceMatchFound = false; + var referenceNames = referenceLookup[branchGrouping.Key.Sha].Select(element => element.Name).ToHashSet(); - if (referenceMatchFound) continue; - foreach (var item in branchGrouping) - { - if (returnedBranches.Add(item)) yield return item; + foreach (var item in branchGrouping) + { + if (!referenceNames.Contains(item.Name)) continue; + if (returnedBranches.Add(item)) yield return item; + referenceMatchFound = true; + } + + if (referenceMatchFound) continue; + foreach (var item in branchGrouping) + { + if (returnedBranches.Add(item)) yield return item; + } } } } diff --git a/src/GitVersion.LibGit2Sharp/Git/Commit.cs b/src/GitVersion.LibGit2Sharp/Git/Commit.cs index f9dd9cfc06..930898ef9e 100644 --- a/src/GitVersion.LibGit2Sharp/Git/Commit.cs +++ b/src/GitVersion.LibGit2Sharp/Git/Commit.cs @@ -1,5 +1,6 @@ using GitVersion.Extensions; using GitVersion.Helpers; +using LibGit2Sharp; namespace GitVersion.Git; @@ -14,7 +15,16 @@ internal sealed class Commit : GitObject, ICommit internal Commit(LibGit2Sharp.Commit innerCommit) : base(innerCommit) { this.innerCommit = innerCommit.NotNull(); - this.parentsLazy = new(() => innerCommit.Parents.Select(parent => new Commit(parent)).ToList()); + this.parentsLazy = new Lazy>(() => innerCommit.Parents.Select(parent => + { + ICommit gvCommit; + if (!CommitCollection.s_commits.TryGetValue(parent, out gvCommit)) + { + gvCommit = new Commit(parent); + CommitCollection.s_commits.Add(parent, gvCommit); + } + return gvCommit; + }).ToList()); When = innerCommit.Committer.When; } diff --git a/src/GitVersion.LibGit2Sharp/Git/CommitCollection.cs b/src/GitVersion.LibGit2Sharp/Git/CommitCollection.cs index c2e33588a4..9300dfe451 100644 --- a/src/GitVersion.LibGit2Sharp/Git/CommitCollection.cs +++ b/src/GitVersion.LibGit2Sharp/Git/CommitCollection.cs @@ -5,13 +5,31 @@ namespace GitVersion.Git; internal sealed class CommitCollection : ICommitCollection { + public static Dictionary s_commits = new Dictionary(); + private readonly ICommitLog innerCollection; private readonly Lazy> commits; internal CommitCollection(ICommitLog collection) { this.innerCollection = collection.NotNull(); - this.commits = new Lazy>(() => [.. this.innerCollection.Select(commit => new Commit(commit))]); + this.commits = new Lazy>(() => { + List commits = new List(); + foreach (var c in this.innerCollection) { + ICommit gvCommit; + if (s_commits.TryGetValue(c, out gvCommit)) + { + commits.Add(gvCommit); + } + else + { + gvCommit = new Commit(c); + commits.Add(gvCommit); + s_commits[c] = gvCommit; + } + } + return commits; + }); } public IEnumerator GetEnumerator() diff --git a/src/GitVersion.LibGit2Sharp/Git/GitRepository.cs b/src/GitVersion.LibGit2Sharp/Git/GitRepository.cs index aea0217adc..fec8f6829d 100644 --- a/src/GitVersion.LibGit2Sharp/Git/GitRepository.cs +++ b/src/GitVersion.LibGit2Sharp/Git/GitRepository.cs @@ -21,13 +21,56 @@ private IRepository RepositoryInstance public string WorkingDirectory => RepositoryInstance.Info.WorkingDirectory; public bool IsHeadDetached => RepositoryInstance.Info.IsHeadDetached; public bool IsShallow => RepositoryInstance.Info.IsShallow; - public IBranch Head => new Branch(RepositoryInstance.Head); - public ITagCollection Tags => new TagCollection(RepositoryInstance.Tags); - public IReferenceCollection Refs => new ReferenceCollection(RepositoryInstance.Refs); - public IBranchCollection Branches => new BranchCollection(RepositoryInstance.Branches); - public ICommitCollection Commits => new CommitCollection(RepositoryInstance.Commits); - public IRemoteCollection Remotes => new RemoteCollection(RepositoryInstance.Network.Remotes); + private IBranch _head = null; + public IBranch Head { + get { + _head ??= new Branch(RepositoryInstance.Head); + return _head; + } + } + + private ITagCollection _tags = null; + public ITagCollection Tags { + get { + _tags ??= new TagCollection(RepositoryInstance.Tags); + return _tags; + } + } + + private IReferenceCollection _refs = null; + public IReferenceCollection Refs { + get { + _refs ??= new ReferenceCollection(RepositoryInstance.Refs); + return _refs; + } + } + + private IBranchCollection _branches = null; + public IBranchCollection Branches { + get { + _branches ??= new BranchCollection(RepositoryInstance.Branches); + return _branches; + } + } + + private ICommitCollection _commits = null; + public ICommitCollection Commits + { + get + { + _commits ??= new CommitCollection(RepositoryInstance.Commits); + return _commits; + } + } + + public IRemoteCollection _remotes = null; + public IRemoteCollection Remotes { + get { + _remotes ??= new RemoteCollection(RepositoryInstance.Network.Remotes); + return _remotes; + } + } public void DiscoverRepository(string? gitDirectory) {