public void ResolveConflicts()

in src/Tasks/Common/ConflictResolution/ConflictResolver.cs [34:148]


        public void ResolveConflicts(IEnumerable<TConflictItem> conflictItems, Func<TConflictItem, string> getItemKey,
            ConflictCallback<TConflictItem> foundConflict, bool commitWinner = true)
        {
            if (conflictItems == null)
            {
                return;
            }

            foreach (var conflictItem in conflictItems)
            {
                var itemKey = getItemKey(conflictItem);

                if (String.IsNullOrEmpty(itemKey))
                {
                    continue;
                }

                TConflictItem existingItem;

                if (_winningItemsByKey.TryGetValue(itemKey, out existingItem))
                {
                    // a conflict was found, determine the winner.
                    var winner = ResolveConflict(existingItem, conflictItem, logUnresolvedConflicts: false);

                    if (winner == null)
                    {
                        //  No winner.  Keep track of the conflictItem, so that if a subsequent
                        //  item wins for this key, both items (for which there was no winner when
                        //  compared to each other) can be counted as conflicts and removed from
                        //  the corresponding list.

                        List<TConflictItem> unresolvedConflictsForKey;
                        if (!_unresolvedConflictItems.TryGetValue(itemKey, out unresolvedConflictsForKey))
                        {
                            unresolvedConflictsForKey = new List<TConflictItem>();
                            _unresolvedConflictItems[itemKey] = unresolvedConflictsForKey;

                            //  This is the first time we hit an unresolved conflict for this key, so
                            //  add the existing item to the unresolved conflicts list
                            unresolvedConflictsForKey.Add(existingItem);
                        }

                        //  Add the new item to the unresolved conflicts list
                        unresolvedConflictsForKey.Add(conflictItem);

                        continue;
                    }

                    TConflictItem loser = conflictItem;
                    if (!ReferenceEquals(winner, existingItem))
                    {
                        // replace existing item
                        if (commitWinner)
                        {
                            _winningItemsByKey[itemKey] = conflictItem;
                        }
                        else
                        {
                            _winningItemsByKey.Remove(itemKey);
                        }
                        loser = existingItem;
                    }

                    foundConflict(winner, loser);

                    //  If there were any other items that tied with the loser, report them as conflicts here
                    //  if they lose against the new winner.  Otherwise, keep them in the unresolved conflict
                    //  list.
                    List<TConflictItem> previouslyUnresolvedConflicts;
                    if(_unresolvedConflictItems.TryGetValue(itemKey, out previouslyUnresolvedConflicts) &&
                        previouslyUnresolvedConflicts.Contains(loser))
                    {
                        List<TConflictItem> newUnresolvedConflicts = new List<TConflictItem>();
                        foreach (var previouslyUnresolvedItem in previouslyUnresolvedConflicts)
                        {
                            //  Don't re-report the item that just lost and was already reported
                            if (object.ReferenceEquals(previouslyUnresolvedItem, loser))
                            {
                                continue;
                            }

                            //  Call ResolveConflict with the new winner and item that previously had an unresolved
                            //  conflict, so that if the previously unresolved conflict loses, the correct message
                            //  will be logged recording that the winner won and why.  If the conflict can't be
                            //  resolved, then keep the previously unresolved conflict in the list of unresolved
                            //  conflicts.
                            var newWinner = ResolveConflict(winner, previouslyUnresolvedItem, logUnresolvedConflicts: true);
                            if (newWinner == winner)
                            {
                                foundConflict(winner, previouslyUnresolvedItem);
                            }
                            else if (newWinner == null)
                            {
                                if (newUnresolvedConflicts.Count == 0)
                                {
                                    newUnresolvedConflicts.Add(winner);
                                }
                                newUnresolvedConflicts.Add(previouslyUnresolvedItem);
                            }

                            
                        }
                        _unresolvedConflictItems.Remove(itemKey);
                        if (newUnresolvedConflicts.Count > 0)
                        {
                            _unresolvedConflictItems[itemKey] = newUnresolvedConflicts;
                        }
                    }
                }
                else if (commitWinner)
                {
                    _winningItemsByKey[itemKey] = conflictItem;
                }
            }
        }