Example #1
0
 private void RemoveMissingItemsWhichAreChildrenOfRenamedItem(FolderMetaData root)
 {
     foreach (string item in renamedItemsToBeCheckedForDeletedChildren)
     {
         RemoveMissingItemsWhichAreChildrenOfRenamedItem(item, root);
     }
 }
Example #2
0
        public void CalculateDiff(string checkoutRootPath, int versionTo, int versionFrom, FolderMetaData checkoutRoot, UpdateReportData updateReportData)
        {
            clientExistingFiles = GetClientExistingFiles(checkoutRootPath, updateReportData);
            clientMissingFiles  = GetClientDeletedFiles(checkoutRootPath, updateReportData);
            string projectRootPath = GetProjectRoot(checkoutRootPath);

            if (updateReportData.Entries != null)
            {
                foreach (EntryData data in updateReportData.Entries)
                {
                    int itemVersionFrom = int.Parse(data.Rev);
                    if (itemVersionFrom < versionFrom)
                    {
                        string rootPath = checkoutRootPath;
                        if (updateReportData.UpdateTarget != null)
                        {
                            rootPath += "/" + updateReportData.UpdateTarget;
                        }

                        string targetPath = rootPath + "/" + data.path;

                        if (targetPath.StartsWith("/"))
                        {
                            targetPath = targetPath.Substring(1);
                        }

                        CalculateChangeBetweenVersions(projectRootPath, targetPath, itemVersionFrom, checkoutRoot, itemVersionFrom, versionFrom);
                    }
                }
            }

            if (versionFrom != versionTo)
            {
                // we have to calculate the difference from the project root
                // this is because we may have a file move from below the checkoutRootPath,
                // which we still need to consider
                FolderMetaData projectRoot = checkoutRoot;
                if (projectRootPath != checkoutRootPath)
                {
                    projectRoot = (FolderMetaData)sourceControlProvider.GetItems(versionTo, projectRootPath, Recursion.None);
                    string path = checkoutRootPath.Substring(0, checkoutRootPath.LastIndexOf('/'));
                    path = path.Substring(path.IndexOf('/') + 1);
                    FolderMetaData result = (FolderMetaData)FindItemOrCreateItem(projectRoot, projectRootPath, path, versionTo, Recursion.None);
                    result.Items.Add(checkoutRoot);
                }

                CalculateChangeBetweenVersions(projectRootPath, -1, projectRoot, versionFrom, versionTo);
            }

            foreach (string missingItem in clientMissingFiles.Values)
            {
                if (sourceControlProvider.ItemExists(checkoutRootPath + "/" + missingItem, versionTo))
                {
                    FindItemOrCreateItem(checkoutRoot, checkoutRootPath, missingItem, versionTo, Recursion.Full);
                }
            }
            FlattenDeletedFolders(checkoutRoot);
            RemoveMissingItemsWhichAreChildrenOfRenamedItem(checkoutRoot);
            VerifyNoMissingItemMetaDataRemained(checkoutRoot);
        }
Example #3
0
 private static void VerifyNoMissingItemMetaDataRemained(FolderMetaData root)
 {
     foreach (ItemMetaData item in root.Items)
     {
         if (item is MissingItemMetaData)
         {
             throw new InvalidOperationException("Found missing item:" + item +
                                                 " but those should not be returned from UpdateDiffCalculator");
         }
         if (item is FolderMetaData)
         {
             VerifyNoMissingItemMetaDataRemained((FolderMetaData)item);
         }
     }
 }
        private void ProcessDeletedItem(string remoteName, SourceItemChange change)
        {
            bool alreadyChangedInCurrentClientState = IsChangeAlreadyCurrentInClientState(ChangeType.Delete,
                                                                                          remoteName,
                                                                                          change.Item.RemoteChangesetId,
                                                                                          clientExistingFiles,
                                                                                          clientMissingFiles);

            if (alreadyChangedInCurrentClientState)
            {
                RemoveMissingItem(remoteName, _root);
                return;
            }

            string folderName      = _checkoutRootPath;
            string remoteNameStart = remoteName.StartsWith(_checkoutRootPath) ? _checkoutRootPath : folderName;

            string[] nameParts = remoteName.Substring(remoteNameStart.Length)
                                 .Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

            FolderMetaData folder = _root;

            for (int i = 0; i < nameParts.Length; i++)
            {
                bool isLastNamePart = i == nameParts.Length - 1;

                if (folderName != "" && !folderName.EndsWith("/"))
                {
                    folderName += "/" + nameParts[i];
                }
                else
                {
                    folderName += nameParts[i];
                }

                bool fullyHandled = HandleDeleteItem(remoteName, change, folderName, ref folder, isLastNamePart);
                if (fullyHandled)
                {
                    break;
                }
            }
            if (nameParts.Length == 0)//we have to delete the checkout root itself
            {
                HandleDeleteItem(remoteName, change, folderName, ref folder, true);
            }
        }
 public UpdateDiffEngine(FolderMetaData root,
                         string checkoutRootPath,
                         int targetVersion,
                         TFSSourceControlProvider sourceControlProvider,
                         Dictionary <string, int> clientExistingFiles,
                         Dictionary <string, string> clientMissingFiles,
                         Dictionary <ItemMetaData, bool> additionForPropertyChangeOnly,
                         List <string> renamedItemsToBeCheckedForDeletedChildren)
 {
     this._root                                     = root;
     this._checkoutRootPath                         = checkoutRootPath;
     this._targetVersion                            = targetVersion;
     this.sourceControlProvider                     = sourceControlProvider;
     this.clientExistingFiles                       = clientExistingFiles;
     this.clientMissingFiles                        = clientMissingFiles;
     this.additionForPropertyChangeOnly             = additionForPropertyChangeOnly;
     this.renamedItemsToBeCheckedForDeletedChildren = renamedItemsToBeCheckedForDeletedChildren;
 }
Example #6
0
 /// This method ensures that we are not sending useless deletes to the client
 /// if a folder is to be deleted, all its children are as well, which we remove
 /// at this phase.
 private static void FlattenDeletedFolders(FolderMetaData parentFolder)
 {
     foreach (ItemMetaData item in parentFolder.Items)
     {
         FolderMetaData folder = item as FolderMetaData;
         if (folder == null)
         {
             continue;
         }
         if (folder is DeleteFolderMetaData)
         {
             folder.Items.Clear();
         }
         else
         {
             FlattenDeletedFolders(folder);
         }
     }
 }
Example #7
0
        private ItemMetaData FindItemOrCreateItem(FolderMetaData root, string pathRoot, string path, int targetVersion, Recursion recursion)
        {
            FolderMetaData folder = root;

            string[]     parts    = path.Split('/');
            string       itemName = pathRoot;
            ItemMetaData item     = null;

            for (int i = 0; i < parts.Length; i++)
            {
                if (itemName != "" && !itemName.EndsWith("/"))
                {
                    itemName += "/" + parts[i];
                }
                else
                {
                    itemName += parts[i];
                }

                item = folder.FindItem(itemName);
                bool lastNamePart = i == parts.Length - 1;
                if (item == null)
                {
                    if (lastNamePart)
                    {
                        item = sourceControlProvider.GetItems(targetVersion, itemName, recursion);
                    }
                    else
                    {
                        FolderMetaData subFolder =
                            (FolderMetaData)sourceControlProvider.GetItems(targetVersion, itemName, recursion);
                        item = subFolder;
                    }
                    item = item ?? new MissingItemMetaData(itemName, targetVersion, false);
                    folder.Items.Add(item);
                }
                if (lastNamePart == false)
                {
                    folder = (FolderMetaData)item;
                }
            }
            return(item);
        }
 private bool RemoveMissingItem(string name, FolderMetaData folder)
 {
     foreach (ItemMetaData item in folder.Items)
     {
         if (item.Name == name && item is MissingItemMetaData)
         {
             folder.Items.Remove(item);
             return(true);
         }
         FolderMetaData subFolder = item as FolderMetaData;
         if (subFolder != null)
         {
             if (RemoveMissingItem(name, subFolder))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Example #9
0
 public ItemMetaData FindItem(string name)
 {
     if (string.Equals(name, this.Name, StringComparison.InvariantCultureIgnoreCase))
     {
         return(this);
     }
     foreach (ItemMetaData item in Items)
     {
         if (string.Equals(item.Name, name, StringComparison.InvariantCultureIgnoreCase))
         {
             return(item);
         }
         FolderMetaData subFolder = item as FolderMetaData;
         if (subFolder != null)
         {
             ItemMetaData result = subFolder.FindItem(name);
             if (result != null)
             {
                 return(result);
             }
         }
     }
     return(null);
 }
Example #10
0
        private static void RemoveMissingItemsWhichAreChildrenOfRenamedItem(string itemName, FolderMetaData root)
        {
            if (itemName.StartsWith("/"))
            {
                itemName = itemName.Substring(1);
            }

            foreach (ItemMetaData data in new List <ItemMetaData>(root.Items))
            {
                string nameMatchingSourceItemConvention = data.Name;
                if (data.Name.StartsWith("/"))
                {
                    nameMatchingSourceItemConvention = data.Name.Substring(1);
                }

                // a child of the currently renamed item
                if (data is MissingItemMetaData &&
                    nameMatchingSourceItemConvention.StartsWith(itemName, StringComparison.InvariantCultureIgnoreCase))
                {
                    root.Items.Remove(data);
                    continue;
                }
                if (data is FolderMetaData)
                {
                    RemoveMissingItemsWhichAreChildrenOfRenamedItem(itemName, (FolderMetaData)data);
                }
            }
        }
Example #11
0
        private void CalculateChangeBetweenVersions(string checkoutRootPath, string changePath, int changeVersion, FolderMetaData root, int sourceVersion, int targetVersion)
        {
            bool updatingForwardInTime = sourceVersion <= targetVersion;
            int  lastVersion           = sourceVersion;

            while (targetVersion != lastVersion)
            {
                int     previousLoopLastVersion = lastVersion;
                LogItem logItem = sourceControlProvider.GetLog(
                    changePath,
                    changeVersion,
                    Math.Min(lastVersion, targetVersion) + 1,
                    Math.Max(lastVersion, targetVersion),
                    Recursion.Full, 256);

                foreach (SourceItemHistory history in Helper.SortHistories(updatingForwardInTime, logItem.History))
                {
                    lastVersion = history.ChangeSetID;
                    if (updatingForwardInTime == false)
                    {
                        lastVersion -= 1;
                    }

                    // we need to go over the changeset in reverse order so we will process
                    // all the files first, and build the folder hierarchy that way
                    for (int i = history.Changes.Count - 1; i >= 0; i--)
                    {
                        UpdateDiffEngine engine = new UpdateDiffEngine(root, checkoutRootPath, targetVersion, sourceControlProvider, clientExistingFiles, clientMissingFiles, additionForPropertyChangeOnly, renamedItemsToBeCheckedForDeletedChildren);
                        SourceItemChange change = history.Changes[i];
                        if (ShouldBeIgnored(change.Item.RemoteName))
                        {
                            continue;
                        }
                        if (IsAddOperation(change, updatingForwardInTime))
                        {
                            engine.Add(change);
                        }
                        else if (IsDeleteOperation(change, updatingForwardInTime))
                        {
                            engine.Delete(change);
                        }
                        else if (IsEditOperation(change))
                        {
                            // We may have edit & rename operations
                            if (IsRenameOperation(change))
                            {
                                engine.Rename(change, updatingForwardInTime);
                            }
                            if (updatingForwardInTime == false)
                            {
                                change.Item.RemoteChangesetId -= 1; // we turn the edit around, basically
                            }
                            engine.Edit(change);
                        }
                        else if (IsRenameOperation(change))
                        {
                            engine.Rename(change, updatingForwardInTime);
                        }
                        else
                        {
                            throw new NotSupportedException("Unsupported change type " + change.ChangeType);
                        }
                    }
                }
                // No change was made, break out
                if (previousLoopLastVersion == lastVersion)
                {
                    break;
                }
            }
        }
Example #12
0
 private void CalculateChangeBetweenVersions(string checkoutRootPath, int checkoutRootVersion, FolderMetaData root, int sourceVersion, int targetVersion)
 {
     CalculateChangeBetweenVersions(checkoutRootPath, checkoutRootPath, checkoutRootVersion, root, sourceVersion, targetVersion);
 }
Example #13
0
 public NoNullAllowedItemsCollection(FolderMetaData parent)
 {
     this.parent = parent;
 }
        private bool HandleDeleteItem(string remoteName, SourceItemChange change, string folderName, ref FolderMetaData folder, bool isLastNamePart)
        {
            ItemMetaData item = folder.FindItem(folderName);

            if (item is DeleteFolderMetaData || item is DeleteMetaData)
            {
                return(true);
            }

            if (item == null)
            {
                if (isLastNamePart)
                {
                    if (change.Item.ItemType == ItemType.File)
                    {
                        item = new DeleteMetaData();
                    }
                    else
                    {
                        item = new DeleteFolderMetaData();
                    }

                    item.Name         = remoteName;
                    item.ItemRevision = change.Item.RemoteChangesetId;
                }
                else
                {
                    item = sourceControlProvider.GetItemsWithoutProperties(_targetVersion, folderName, Recursion.None);
                    if (item == null)
                    {
                        item              = new DeleteFolderMetaData();
                        item.Name         = folderName;
                        item.ItemRevision = _targetVersion;
                    }
                }
                folder.Items.Add(item);
            }
            else if (isLastNamePart)        // we need to revert the item addition
            {
                if (item.OriginallyDeleted) // convert back into a delete
                {
                    folder.Items.Remove(item);
                    if (change.Item.ItemType == ItemType.File)
                    {
                        item = new DeleteMetaData();
                    }
                    else
                    {
                        item = new DeleteFolderMetaData();
                    }

                    item.Name         = remoteName;
                    item.ItemRevision = change.Item.RemoteChangesetId;
                    folder.Items.Add(item);
                }
                else if (item is StubFolderMetaData)
                {
                    DeleteFolderMetaData removeFolder = new DeleteFolderMetaData();
                    removeFolder.Name         = item.Name;
                    removeFolder.ItemRevision = _targetVersion;
                    folder.Items.Remove(item);
                    folder.Items.Add(removeFolder);
                }
                else if (additionForPropertyChangeOnly.ContainsKey(item) && additionForPropertyChangeOnly[item])
                {
                    ItemMetaData removeFolder = item is FolderMetaData
                                                    ? (ItemMetaData) new DeleteFolderMetaData()
                                                    : new DeleteMetaData();
                    removeFolder.Name         = item.Name;
                    removeFolder.ItemRevision = _targetVersion;
                    folder.Items.Remove(item);
                    folder.Items.Add(removeFolder);
                }
                else if (item is MissingItemMetaData && ((MissingItemMetaData)item).Edit == true)
                {
                    ItemMetaData removeFolder = new DeleteMetaData();
                    removeFolder.Name         = item.Name;
                    removeFolder.ItemRevision = _targetVersion;
                    folder.Items.Remove(item);
                    folder.Items.Add(removeFolder);
                }
                else
                {
                    folder.Items.Remove(item);
                }
            }
            folder = (item as FolderMetaData) ?? folder;
            return(false);
        }
        private void ProcessAddedOrUpdatedItem(string remoteName, SourceItemChange change, bool propertyChange, bool edit)
        {
            bool alreadyInClientCurrentState = IsChangeAlreadyCurrentInClientState(ChangeType.Add,
                                                                                   remoteName,
                                                                                   change.Item.RemoteChangesetId,
                                                                                   clientExistingFiles,
                                                                                   clientMissingFiles);

            if (alreadyInClientCurrentState)
            {
                return;
            }

            if (string.Equals(remoteName, _checkoutRootPath, StringComparison.InvariantCultureIgnoreCase))
            {
                ItemMetaData item = sourceControlProvider.GetItems(_targetVersion, remoteName, Recursion.None);
                if (item != null)
                {
                    _root.Properties = item.Properties;
                }
            }
            else
            {
                FolderMetaData folder   = _root;
                string         itemName = _checkoutRootPath;
                string[]       nameParts;
                if (_checkoutRootPath != "")
                {
                    nameParts = remoteName.Substring(_checkoutRootPath.Length + 1).Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                }
                else
                {
                    nameParts = remoteName.Split('/');
                }

                for (int i = 0; i < nameParts.Length; i++)
                {
                    bool lastNamePart = false;
                    if (i == nameParts.Length - 1)
                    {
                        lastNamePart = true;
                    }

                    if (itemName != "" && !itemName.EndsWith("/"))
                    {
                        itemName += "/" + nameParts[i];
                    }
                    else
                    {
                        itemName += nameParts[i];
                    }

                    ItemMetaData item = folder.FindItem(itemName);
                    if (item == null ||
                        (
                            lastNamePart &&
                            item.Revision < change.Item.RemoteChangesetId &&
                            !(item is DeleteFolderMetaData) &&
                            !(item is DeleteMetaData)
                        )
                        )
                    {
                        if (item != null)
                        {
                            folder.Items.Remove(item);
                        }
                        item = sourceControlProvider.GetItems(_targetVersion, itemName, Recursion.None);
                        if (item == null)
                        {
                            // TFS will report renames even for deleted items,
                            // since TFS reported that this was renamed, but it doesn't exists
                            // in this revision, we know it is a case of renaming a deleted file.
                            // We can safely ignore this and any of its children.
                            if (IsRenameOperation(change))
                            {
                                return;
                            }
                            if (lastNamePart && propertyChange)
                            {
                                return;
                            }
                            item = new MissingItemMetaData(itemName, _targetVersion, edit);
                        }
                        if (!lastNamePart)
                        {
                            StubFolderMetaData stubFolder = new StubFolderMetaData();
                            stubFolder.RealFolder       = (FolderMetaData)item;
                            stubFolder.Name             = item.Name;
                            stubFolder.ItemRevision     = item.ItemRevision;
                            stubFolder.PropertyRevision = item.PropertyRevision;
                            stubFolder.LastModifiedDate = item.LastModifiedDate;
                            stubFolder.Author           = item.Author;
                            item = stubFolder;
                        }
                        folder.Items.Add(item);
                        SetAdditionForPropertyChangeOnly(item, propertyChange);
                    }
                    else if ((item is StubFolderMetaData) && lastNamePart)
                    {
                        folder.Items.Remove(item);
                        folder.Items.Add(((StubFolderMetaData)item).RealFolder);
                    }
                    else if (((item is DeleteFolderMetaData) || (item is DeleteMetaData)) && IsAddOperation(change))
                    {
                        if (!propertyChange)
                        {
                            folder.Items.Remove(item);
                            item = sourceControlProvider.GetItems(change.Item.RemoteChangesetId, itemName, Recursion.None);
                            item.OriginallyDeleted = true;
                            folder.Items.Add(item);
                        }
                    }
                    if (lastNamePart == false)
                    {
                        folder = (FolderMetaData)item;
                    }
                }
            }
        }
 public void SetParent(FolderMetaData parentFolder)
 {
     parent = parentFolder;
 }