static Commit GetMainlineTip(GitVersionContext context)
{
var mainlineBranchConfigs = context.FullConfiguration.Branches.Where(b => b.Value.IsMainline == true).ToList();
var seenMainlineTips = new List<string>();
var mainlineBranches = context.Repository.Branches
.Where(b =>
{
return mainlineBranchConfigs.Any(c => Regex.IsMatch(b.FriendlyName, c.Key));
})
.Where(b =>
{
if (seenMainlineTips.Contains(b.Tip.Sha))
{
Logger.WriteInfo("Multiple possible mainlines pointing at the same commit, dropping " + b.FriendlyName);
return false;
}
seenMainlineTips.Add(b.Tip.Sha);
return true;
})
.Select(b => new
{
MergeBase = context.Repository.ObjectDatabase.FindMergeBase(b.Tip, context.CurrentCommit),
Branch = b
})
.Where(a => a.MergeBase != null)
.GroupBy(b => b.MergeBase.Sha, b => b.Branch)
.ToDictionary(b => b.Key, b => b.ToList());
var allMainlines = mainlineBranches.Values.SelectMany(branches => branches.Select(b => b.FriendlyName));
Logger.WriteInfo("Found possible mainline branches: " + string.Join(", ", allMainlines));
// Find closest mainline branch
var firstMatchingCommit = context.CurrentBranch.Commits.First(c => mainlineBranches.ContainsKey(c.Sha));
var possibleMainlineBranches = mainlineBranches[firstMatchingCommit.Sha];
if (possibleMainlineBranches.Count == 1)
{
var mainlineBranch = possibleMainlineBranches[0];
Logger.WriteInfo("Mainline for current branch is " + mainlineBranch.FriendlyName);
return mainlineBranch.Tip;
}
var chosenMainline = possibleMainlineBranches[0];
Logger.WriteInfo(string.Format(
"Multiple mainlines ({0}) have the same merge base for the current branch, choosing {1} because we found that branch first...",
string.Join(", ", possibleMainlineBranches.Select(b => b.FriendlyName)),
chosenMainline.FriendlyName));
return chosenMainline.Tip;
}