public async Task <IntegrationBranchResult> FindAndCreateIntegrationBranches(BranchGroupCompleteData downstreamDetails, IEnumerable <string> initialUpstreamBranchGroups, AttemptMergeDelegate doMerge) { // 1. Find branches that conflict // 2. Create integration branches for them // 3. Add the integration branch for ourselves foreach (var upstream in initialUpstreamBranchGroups) { if (await repository.IsBadBranch(upstream)) { // A branch that was directly upstream had updates pending return(new IntegrationBranchResult { PendingUpdates = true }); } } var result = await FindConflicts(downstreamDetails.GroupName, initialUpstreamBranchGroups, doMerge); if (result.PendingUpdates) { return(result); } var newIntegrationBranches = new List <string>(); using (var work = workFactory.CreateUnitOfWork()) { foreach (var conflict in result.Conflicts) { // I need an integration branch! var integrationBranch = await settings.FindIntegrationBranchForConflict(conflict.BranchA.GroupName, conflict.BranchB.GroupName, downstreamDetails.UpstreamBranchGroups); if (downstreamDetails.UpstreamBranchGroups.Contains(integrationBranch)) { // You already have one! - Maz Kanata continue; } var originalIntegrationBranch = integrationBranch; if (integrationBranch == null) { if (conflict.BranchA.GroupName == downstreamDetails.GroupName || conflict.BranchB.GroupName == downstreamDetails.GroupName) { continue; } integrationBranch = await integrationNaming.GetIntegrationBranchName(conflict.BranchA.GroupName, conflict.BranchB.GroupName); settings.CreateIntegrationBranch(conflict.BranchA.GroupName, conflict.BranchB.GroupName, integrationBranch, work); #pragma warning disable CS4014 orchestration.EnqueueAction(new MergeDownstreamAction(integrationBranch)); #pragma warning restore } if (originalIntegrationBranch != null && (conflict.BranchA.GroupName == downstreamDetails.GroupName || conflict.BranchB.GroupName == downstreamDetails.GroupName)) { // There was an integration branch with the current branch and an upstream branch. Flip it around and consolidate! newIntegrationBranches.Add(integrationBranch); settings.AddBranchPropagation(integrationBranch, downstreamDetails.GroupName, work); settings.RemoveBranchPropagation(downstreamDetails.GroupName, integrationBranch, work); #pragma warning disable CS4014 orchestration.EnqueueAction(new MergeDownstreamAction(downstreamDetails.GroupName)); orchestration.EnqueueAction(new ConsolidateMergedAction(integrationBranch, downstreamDetails.GroupName)); #pragma warning restore } else if (!downstreamDetails.UpstreamBranchGroups.Any(b => b == integrationBranch)) { newIntegrationBranches.Add(integrationBranch); settings.AddBranchPropagation(integrationBranch, downstreamDetails.GroupName, work); } } await work.CommitAsync(); } return(new IntegrationBranchResult { Conflicts = result.Conflicts, AddedBranches = newIntegrationBranches, }); }