Skip to content

Commit a4e734a

Browse files
authored
Merge pull request #2756 from Evangelink/yield-throw
Split throw part from the yielding function
2 parents 4779963 + e91d69a commit a4e734a

File tree

2 files changed

+51
-32
lines changed

2 files changed

+51
-32
lines changed

src/GitVersion.Core.Tests/Core/RepositoryStoreTests.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Microsoft.Extensions.DependencyInjection;
77
using NUnit.Framework;
88
using Shouldly;
9+
using NSubstitute.ExceptionExtensions;
910

1011
namespace GitVersion.Core.Tests
1112
{
@@ -204,5 +205,15 @@ public void FindsCorrectMergeBaseForMultipleForwardMerges()
204205
releaseBranchMergeBase.ShouldBe(expectedReleaseMergeBase);
205206
developMergeBase.ShouldBe(expectedDevelopMergeBase);
206207
}
208+
209+
[Test]
210+
public void GetBranchesContainingCommitThrowsDirectlyOnNullCommit()
211+
{
212+
using var fixture = new EmptyRepositoryFixture();
213+
var fixtureRepository = fixture.Repository.ToGitRepository();
214+
var gitRepoMetadataProvider = new RepositoryStore(log, fixtureRepository);
215+
216+
Assert.Throws<ArgumentNullException>(() => gitRepoMetadataProvider.GetBranchesContainingCommit(null));
217+
}
207218
}
208219
}

src/GitVersion.Core/Core/RepositoryStore.cs

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -239,52 +239,60 @@ public IEnumerable<IBranch> ExcludingBranches(IEnumerable<IBranch> branchesToExc
239239
// TODO Should we cache this?
240240
public IEnumerable<IBranch> GetBranchesContainingCommit(ICommit commit, IEnumerable<IBranch> branches = null, bool onlyTrackedBranches = false)
241241
{
242-
branches ??= repository.Branches.ToList();
243-
static bool IncludeTrackedBranches(IBranch branch, bool includeOnlyTracked) => includeOnlyTracked && branch.IsTracking || !includeOnlyTracked;
244-
245242
if (commit == null)
246243
{
247244
throw new ArgumentNullException(nameof(commit));
248245
}
249246

250-
using (log.IndentLog($"Getting branches containing the commit '{commit.Id}'."))
247+
return InnerGetBranchesContainingCommit(commit, branches, onlyTrackedBranches, repository, log);
248+
249+
static bool IncludeTrackedBranches(IBranch branch, bool includeOnlyTracked) => includeOnlyTracked && branch.IsTracking || !includeOnlyTracked;
250+
251+
// Yielding part is split from the main part of the method to avoid having the exception check performed lazily.
252+
// Details at https://github.com/GitTools/GitVersion/issues/2755
253+
static IEnumerable<IBranch> InnerGetBranchesContainingCommit(ICommit commit, IEnumerable<IBranch> branches, bool onlyTrackedBranches, IGitRepository repository, ILog log)
251254
{
252-
var directBranchHasBeenFound = false;
253-
log.Info("Trying to find direct branches.");
254-
// TODO: It looks wasteful looping through the branches twice. Can't these loops be merged somehow? @asbjornu
255-
var branchList = branches.ToList();
256-
foreach (var branch in branchList)
255+
branches ??= repository.Branches.ToList();
256+
257+
using (log.IndentLog($"Getting branches containing the commit '{commit.Id}'."))
257258
{
258-
if (branch.Tip != null && branch.Tip.Sha != commit.Sha || IncludeTrackedBranches(branch, onlyTrackedBranches))
259+
var directBranchHasBeenFound = false;
260+
log.Info("Trying to find direct branches.");
261+
// TODO: It looks wasteful looping through the branches twice. Can't these loops be merged somehow? @asbjornu
262+
var branchList = branches.ToList();
263+
foreach (var branch in branchList)
259264
{
260-
continue;
265+
if (branch.Tip != null && branch.Tip.Sha != commit.Sha || IncludeTrackedBranches(branch, onlyTrackedBranches))
266+
{
267+
continue;
268+
}
269+
270+
directBranchHasBeenFound = true;
271+
log.Info($"Direct branch found: '{branch}'.");
272+
yield return branch;
261273
}
262274

263-
directBranchHasBeenFound = true;
264-
log.Info($"Direct branch found: '{branch}'.");
265-
yield return branch;
266-
}
275+
if (directBranchHasBeenFound)
276+
{
277+
yield break;
278+
}
267279

268-
if (directBranchHasBeenFound)
269-
{
270-
yield break;
271-
}
280+
log.Info($"No direct branches found, searching through {(onlyTrackedBranches ? "tracked" : "all")} branches.");
281+
foreach (var branch in branchList.Where(b => IncludeTrackedBranches(b, onlyTrackedBranches)))
282+
{
283+
log.Info($"Searching for commits reachable from '{branch}'.");
272284

273-
log.Info($"No direct branches found, searching through {(onlyTrackedBranches ? "tracked" : "all")} branches.");
274-
foreach (var branch in branchList.Where(b => IncludeTrackedBranches(b, onlyTrackedBranches)))
275-
{
276-
log.Info($"Searching for commits reachable from '{branch}'.");
285+
var commits = GetCommitsReacheableFrom(repository, commit, branch);
277286

278-
var commits = GetCommitsReacheableFrom(commit, branch);
287+
if (!commits.Any())
288+
{
289+
log.Info($"The branch '{branch}' has no matching commits.");
290+
continue;
291+
}
279292

280-
if (!commits.Any())
281-
{
282-
log.Info($"The branch '{branch}' has no matching commits.");
283-
continue;
293+
log.Info($"The branch '{branch}' has a matching commit.");
294+
yield return branch;
284295
}
285-
286-
log.Info($"The branch '{branch}' has a matching commit.");
287-
yield return branch;
288296
}
289297
}
290298
}
@@ -474,7 +482,7 @@ private IEnumerable<BranchCommit> GetMergeCommitsForBranch(IBranch branch, Confi
474482
return branchMergeBases;
475483
}
476484

477-
private IEnumerable<ICommit> GetCommitsReacheableFrom(ICommit commit, IBranch branch)
485+
private static IEnumerable<ICommit> GetCommitsReacheableFrom(IGitRepository repository, ICommit commit, IBranch branch)
478486
{
479487
var filter = new CommitFilter
480488
{

0 commit comments

Comments
 (0)