Skip to content

Commit 4db6cb7

Browse files
committed
Various fixes for GH-2967
1 parent 4d12ab0 commit 4db6cb7

File tree

3 files changed

+49
-14
lines changed

3 files changed

+49
-14
lines changed

src/GitVersion.Core/Configuration/ConfigExtensions.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,16 @@ public static class ConfigExtensions
99
{
1010
public static BranchConfig? GetConfigForBranch(this Config config, string? branchName)
1111
{
12-
if (branchName == null) throw new ArgumentNullException(nameof(branchName));
12+
if (branchName == null)
13+
{
14+
throw new ArgumentNullException(nameof(branchName));
15+
}
16+
17+
if (config?.Branches is null)
18+
{
19+
return null;
20+
}
21+
1322
var matches = config.Branches
1423
.Where(b => Regex.IsMatch(branchName, b.Value?.Regex, RegexOptions.IgnoreCase))
1524
.ToArray();

src/GitVersion.Core/Core/RepositoryStore.cs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,14 @@ public ICommit GetBaseVersionSource(ICommit currentBranchTip)
137137
throw new GitVersionException($"Cannot find commit {currentBranchTip}. Please ensure that the repository is an unshallow clone with `git fetch --unshallow`.", exception);
138138
}
139139
}
140+
140141
public IEnumerable<ICommit> GetMainlineCommitLog(ICommit? baseVersionSource, ICommit? mainlineTip)
141142
{
143+
if (mainlineTip is null)
144+
{
145+
return Enumerable.Empty<ICommit>();
146+
}
147+
142148
var filter = new CommitFilter
143149
{
144150
IncludeReachableFrom = mainlineTip,
@@ -149,6 +155,7 @@ public IEnumerable<ICommit> GetMainlineCommitLog(ICommit? baseVersionSource, ICo
149155

150156
return this.repository.Commits.QueryBy(filter);
151157
}
158+
152159
public IEnumerable<ICommit> GetMergeBaseCommits(ICommit? mergeCommit, ICommit? mergedHead, ICommit? findMergeBase)
153160
{
154161
var filter = new CommitFilter
@@ -289,20 +296,20 @@ static IEnumerable<IBranch> InnerGetBranchesContainingCommit(ICommit commit, IEn
289296
public Dictionary<string, List<IBranch>> GetMainlineBranches(ICommit commit, IEnumerable<KeyValuePair<string, BranchConfig?>>? mainlineBranchConfigs) =>
290297
this.repository.Branches
291298
.Where(b => mainlineBranchConfigs?.Any(c => c.Value?.Regex != null && Regex.IsMatch(b.Name.Friendly, c.Value.Regex)) == true)
292-
.Select(b => new
293-
{
294-
MergeBase = FindMergeBase(b.Tip!, commit),
295-
Branch = b
296-
})
297-
.Where(a => a.MergeBase != null)
298-
.GroupBy(b => b.MergeBase!.Sha, b => b.Branch)
299+
.Select(b => new { Origin = FindBranchOrigin(b, commit), Branch = b })
300+
.Where(a => a.Origin != null)
301+
.GroupBy(b => b.Origin?.Sha, b => b.Branch)
299302
.ToDictionary(b => b.Key, b => b.ToList());
300303

304+
private ICommit FindBranchOrigin(IBranch branch, ICommit commit) =>
305+
FindMergeBase(branch.Tip!, commit) ?? FindCommitBranchWasBranchedFrom(branch, null).Commit;
306+
307+
301308
/// <summary>
302309
/// Find the commit where the given branch was branched from another branch.
303310
/// If there are multiple such commits and branches, tries to guess based on commit histories.
304311
/// </summary>
305-
public BranchCommit FindCommitBranchWasBranchedFrom(IBranch branch, Config configuration, params IBranch[] excludedBranches)
312+
public BranchCommit FindCommitBranchWasBranchedFrom(IBranch branch, Config? configuration, params IBranch[] excludedBranches)
306313
{
307314
if (branch == null)
308315
{
@@ -456,6 +463,7 @@ private IEnumerable<BranchCommit> GetMergeCommitsForBranch(IBranch branch, Confi
456463
return findMergeBase == null ? BranchCommit.Empty : new BranchCommit(findMergeBase, otherBranch);
457464

458465
})
466+
.Where(b => b.Commit is not null)
459467
.OrderByDescending(b => b.Commit.When)
460468
.ToList();
461469
this.mergeBaseCommitsCache.Add(branch, branchMergeBases);

src/GitVersion.Core/VersionCalculation/MainlineVersionCalculator.cs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,28 @@ private IBranch GetMainline(ICommit? baseVersionSource)
126126
var mainlineBranchConfigs = context.FullConfiguration?.Branches.Where(b => b.Value?.IsMainline == true).ToList();
127127
var mainlineBranches = this.repositoryStore.GetMainlineBranches(context.CurrentCommit!, mainlineBranchConfigs);
128128

129-
var allMainlines = mainlineBranches.Values.SelectMany(branches => branches.Select(b => b.Name.Friendly));
130-
this.log.Info("Found possible mainline branches: " + string.Join(", ", allMainlines));
129+
if (!mainlineBranches.Any())
130+
{
131+
throw new WarningException("No mainline branches found!");
132+
}
133+
134+
var mainlineBranchNames = mainlineBranches.Values.SelectMany(branches => branches.Select(b => b.Name.Friendly));
135+
this.log.Info("Found possible mainline branches: " + string.Join(", ", mainlineBranchNames));
131136

132137
// Find closest mainline branch
133-
var firstMatchingCommit = context.CurrentBranch?.Commits.First(c => mainlineBranches.ContainsKey(c.Sha));
138+
var firstMatchingCommit = context.CurrentBranch?.Commits.FirstOrDefault(c => mainlineBranches.ContainsKey(c.Sha));
139+
if (firstMatchingCommit is null)
140+
{
141+
var mainlineBranchList = mainlineBranches.Values.SelectMany(x => x).ToList();
142+
return FindMainlineBranch(mainlineBranchList, baseVersionSource, context.CurrentCommit);
143+
}
144+
134145
var possibleMainlineBranches = mainlineBranches[firstMatchingCommit!.Sha];
146+
return FindMainlineBranch(possibleMainlineBranches, baseVersionSource, firstMatchingCommit);
147+
}
135148

149+
private IBranch FindMainlineBranch(List<IBranch> possibleMainlineBranches, ICommit? baseVersionSource, ICommit? firstMatchingCommit)
150+
{
136151
if (possibleMainlineBranches.Count == 1)
137152
{
138153
var mainlineBranch = possibleMainlineBranches[0];
@@ -144,11 +159,14 @@ private IBranch GetMainline(ICommit? baseVersionSource)
144159
if (possibleMainlineBranches.Any(context.CurrentBranch!.Equals))
145160
{
146161
this.log.Info($"Choosing {context.CurrentBranch} as mainline because it is the current branch");
147-
return context.CurrentBranch;
162+
return context.CurrentBranch!;
148163
}
149164

150165
// prefer a branch on which the merge base was a direct commit, if there is such a branch
151-
var firstMatchingCommitBranch = possibleMainlineBranches.FirstOrDefault(b => this.repositoryStore.IsCommitOnBranch(baseVersionSource, b, firstMatchingCommit));
166+
var firstMatchingCommitBranch = firstMatchingCommit != null
167+
? possibleMainlineBranches.FirstOrDefault(b => this.repositoryStore.IsCommitOnBranch(baseVersionSource, b, firstMatchingCommit))
168+
: null;
169+
152170
if (firstMatchingCommitBranch != null)
153171
{
154172
var message = string.Format(

0 commit comments

Comments
 (0)