private void addDelete(CCBatchedItem item) { string removeItem = null; foreach (KeyValuePair <string, CCBatchedItem> deleteItemInlist in m_unresolvedDeletes) { if (ClearCasePath.IsSubItem(item.Target, deleteItemInlist.Value.Target)) { // Parent delete is already added, just return. return; } else if (ClearCasePath.IsSubItem(deleteItemInlist.Value.Target, item.Target)) { // A child delete is already added, remove the child delete. removeItem = deleteItemInlist.Key; break; } } if (!string.IsNullOrEmpty(removeItem)) { m_unresolvedDeletes.Remove(removeItem); } m_unresolvedDeletes.Add(item.Target, item); }
private void addRename(CCBatchedItem item) { string removeItem = null; foreach (KeyValuePair <string, CCBatchedItem> renameItemInlist in m_unresolvedRenames) { if (ClearCasePath.Equals(ClearCasePath.MakeRelative(item.Target, renameItemInlist.Value.Target), ClearCasePath.MakeRelative(item.Source, renameItemInlist.Value.Source))) { // Parent rename is already added, just return. return; } else if (ClearCasePath.Equals(ClearCasePath.MakeRelative(renameItemInlist.Value.Target, item.Target), ClearCasePath.MakeRelative(renameItemInlist.Value.Source, item.Source))) { // A child rename is already, remove the child rename. removeItem = renameItemInlist.Key; break; } } if (!string.IsNullOrEmpty(removeItem)) { m_unresolvedRenames.Remove(removeItem); } m_unresolvedRenames.Add(item.Target, item); }
private void scheduleItem(CCBatchedItem lowPriorityItem, CCBatchedItem highPriorityItem) { if (lowPriorityItem.ConflictItem == null) { lowPriorityItem.ConflictItem = highPriorityItem; } else { Debug.Assert(lowPriorityItem.ConflictItem == highPriorityItem, "Item conflicted with two different items."); } }
internal void Add(CCBatchedItem item) { if (item == null) { throw new ArgumentNullException("item"); } if (item.Action == WellKnownChangeActionId.Delete) { addDelete(item); } else if (item.Action == WellKnownChangeActionId.Rename) { addRename(item); } else if (item.Action == WellKnownChangeActionId.Add) { m_unresolvedAdds.Add(item.Target, item); } else if (item.Action == WellKnownChangeActionId.Edit) { m_unresolvedEdits.Add(item); } }
private int breakCycle(CCBatchedItem item) { /* * rename A B * rename B A * * becomes * * rename A <intermediate> * rename B A * rename <intermediate> B * * the conflict is from A to B */ if (item.Action != WellKnownChangeActionId.Rename) { throw new UnresolvableConflictException("Don't know how to break non-rename cycles"); } if (item.Resolved) { return(item.Priority); } string intermediate = getIntermediateName(item.Target); CCBatchedItem intermediate1 = new CCBatchedItem( item.Source, intermediate, WellKnownChangeActionId.Rename, item.DownloadItem, item.ItemTypeReferenceName, item.InternalActionId, null); intermediate1.Priority = item.Priority; item.ConflictItem.Priority++; CCBatchedItem intermediate2 = new CCBatchedItem( intermediate, item.Target, WellKnownChangeActionId.Rename, item.DownloadItem, item.ItemTypeReferenceName, item.InternalActionId, null); intermediate2.Priority = item.ConflictItem.Priority + 1; m_resolvedChanges.Add(intermediate1); m_resolvedChanges.Add(intermediate2); // remove the old change item.Resolved = true; m_unresolvedChanges.Remove(item); if (item.ConflictItem.ConflictItem != null && item.ConflictItem.ConflictItem.ID == item.ID) { item.ConflictItem.Resolved = true; m_unresolvedChanges.Remove(item.ConflictItem); m_resolvedChanges.Add(item.ConflictItem); } else { intermediate2.Priority = breakCycle(item.ConflictItem); } return(item.ConflictItem.Priority); }
public ReadOnlyCollection <CCBatchedItem> Resolve() { detectConflicts(); // walk backwards so that RemoveAt can work // without the removals affecting indexing for (int i = m_unresolvedChanges.Count - 1; i >= 0; i--) { CCBatchedItem item = m_unresolvedChanges[i]; if (item.ConflictItem == null) { item.Resolved = true; m_resolvedChanges.Add(item); m_unresolvedChanges.RemoveAt(i); } } if (m_unresolvedChanges.Count != 0) { int currentCount = m_unresolvedChanges.Count; int prevCount = -1; // detect and remove priority issues while (currentCount > 0 && prevCount != currentCount) { // resolve cases that can be solved just with priority adjustment for (int i = m_unresolvedChanges.Count - 1; i >= 0; i--) { CCBatchedItem item = m_unresolvedChanges[i]; // if the conflict chain ends with the next item // or the next item in the chain is already resolved // then resolve by bumping our priority if (item.ConflictItem.ConflictItem == null || item.ConflictItem.Resolved) { item.Resolved = true; item.Priority = item.ConflictItem.Priority + 1; m_resolvedChanges.Add(item); m_unresolvedChanges.RemoveAt(i); } } // identify cycles for (int i = 0; i < m_unresolvedChanges.Count; i++) { CCBatchedItem item = m_unresolvedChanges[i]; CCBatchedItem next = item.ConflictItem; while (next != null) { if (next.ConflictItem != null && next.ConflictItem.ID == item.ID) { //ToDo breakCycle(item); breakCycle(item); break; } next = next.ConflictItem; } } prevCount = currentCount; currentCount = m_unresolvedChanges.Count; } } Debug.Assert(m_unresolvedChanges.Count == 0, "Unable to resolve pending changes"); int highestPriority = 0; foreach (CCBatchedItem item in m_resolvedChanges) { if (item.Priority > highestPriority) { highestPriority = item.Priority; } } // Delay all Edits and Deletes to be processed at last. foreach (CCBatchedItem editItem in m_unresolvedEdits) { editItem.Priority = editItem.Priority + highestPriority + 1; m_resolvedChanges.Add(editItem); } foreach (CCBatchedItem deleteItem in m_unresolvedDeletes.Values) { deleteItem.Priority = deleteItem.Priority + highestPriority + 1; m_resolvedChanges.Add(deleteItem); } m_resolvedChanges.Sort( delegate(CCBatchedItem lhs, CCBatchedItem rhs) { return(lhs.Priority.CompareTo(rhs.Priority)); } ); return(new ReadOnlyCollection <CCBatchedItem>(m_resolvedChanges)); }