Пример #1
0
        public void RefreshItem(GitItem item, SvnNodeKind nodeKind)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            RefreshPath(item.FullPath, nodeKind);

            IGitItemUpdate updateItem = (IGitItemUpdate)item;

            if (!updateItem.IsStatusClean())
            {
                // Ok, the status update did not refresh the item requesting to be refreshed
                // That means the item is not here or RefreshPath would have added it

                GitItem other;
                if (_map.TryGetValue(item.FullPath, out other) && other != item)
                {
                    updateItem.RefreshTo(other); // This item is no longer current; but we have the status anyway
                }
                else
                {
                    Debug.Assert(false, "RefreshPath did not deliver up to date information",
                                 "The RefreshPath public api promises delivering up to date data, but none was received");

                    updateItem.RefreshTo(item.Exists ? NoSccStatus.NotVersioned : NoSccStatus.NotExisting, SvnNodeKind.Unknown);
                }
            }

            Debug.Assert(updateItem.IsStatusClean(), "The item requesting to be updated is updated");
        }
Пример #2
0
        /// <summary>
        /// Refreshes the specified path using the specified depth
        /// </summary>
        /// <param name="path">A normalized path</param>
        /// <param name="pathKind"></param>
        /// <param name="depth"></param>
        /// <remarks>
        /// If the path is a file and depth is greater that <see cref="GitDepth.Empty"/> the parent folder is walked instead.
        ///
        /// <para>This method guarantees that after calling it at least one up-to-date item exists
        /// in the statusmap for <paramref name="path"/>. If we can not find information we create
        /// an unspecified item
        /// </para>
        /// </remarks>
        void RefreshPath(string path, SvnNodeKind pathKind)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }

            string walkPath         = path;
            bool   walkingDirectory = false;

            switch (pathKind)
            {
            case SvnNodeKind.Directory:
                walkingDirectory = true;
                break;

            case SvnNodeKind.File:
                walkPath         = SvnTools.GetNormalizedDirectoryName(path);
                walkingDirectory = true;
                break;

            default:
                try
                {
                    if (File.Exists(path))     // ### Not long path safe
                    {
                        pathKind = SvnNodeKind.File;
                        goto case SvnNodeKind.File;
                    }
                }
                catch (PathTooLongException)
                { /* Fall through */ }
                break;
            }

            GitStatusArgs args = new GitStatusArgs();

            args.IncludeUnversioned = true;
            args.IncludeUnmodified  = true;
            args.IncludeIgnored     = true;
            //args.IncludeDirectories = true;
            args.IncludeSubmodules     = true;
            args.GenerateVersionedDirs = true;

            lock (_lock)
            {
                GitDirectory        directory;
                IGitDirectoryUpdate updateDir;
                GitItem             walkItem;

                // We get more information for free, lets use that to update other items
                if (_dirMap.TryGetValue(walkPath, out directory))
                {
                    updateDir = directory;
                    updateDir.TickAll();
                }
                else
                {
                    // No existing directory instance, let's create one
                    updateDir         = directory = new GitDirectory(Context, walkPath);
                    _dirMap[walkPath] = directory;
                }

                walkItem = directory.Directory;

                bool     ok;
                bool     statSelf  = false;
                bool     noWcAtAll = false;
                string[] root;

                // Don't retry file open/read operations on failure. These would only delay the result
                // (default number of delays = 100)
                //using (new SharpGit.Implementation.GitFsOperationRetryOverride(0))
                try
                {
                    _root = null;
                    ok    = _client.Status(walkPath, args, RefreshCallback);
                }
                catch
                { ok = false; }
                finally
                {
                    root = _root;
                }

                if (!ok)
                {
                    statSelf = true;
                }
                else if (directory != null)
                {
                    walkItem = directory.Directory; // Might have changed via casing
                }
                if (!statSelf)
                {
                    if (((IGitItemUpdate)walkItem).ShouldRefresh())
                    {
                        statSelf = true;
                    }
                    else if (walkingDirectory && !walkItem.IsVersioned)
                    {
                        statSelf = true;
                    }
                }

                if (statSelf)
                {
                    // Git did not stat the items for us.. Let's make something up

                    if (walkingDirectory)
                    {
                        StatDirectory(walkPath, directory, noWcAtAll);
                    }
                    else
                    {
                        // Just stat the item passed and nothing else in the Depth.Empty case

                        if (walkItem == null)
                        {
                            string truepath = SvnTools.GetTruePath(walkPath); // Gets the on-disk casing if it exists

                            StoreItem(walkItem = CreateItem(truepath ?? walkPath,
                                                            (truepath != null) ? NoSccStatus.NotVersioned : NoSccStatus.NotExisting, SvnNodeKind.Unknown));
                        }
                        else
                        {
                            ((IGitItemUpdate)walkItem).RefreshTo(walkItem.Exists ? NoSccStatus.NotVersioned : NoSccStatus.NotExisting, SvnNodeKind.Unknown);
                        }
                    }
                }

                if (directory != null)
                {
                    foreach (IGitItemUpdate item in directory)
                    {
                        if (item.IsItemTicked()) // These items were not found in the stat calls
                        {
                            item.RefreshTo(NoSccStatus.NotExisting, SvnNodeKind.Unknown);
                        }
                    }

                    if (updateDir.ScheduleForCleanup)
                    {
                        ScheduleForCleanup(directory); // Handles removing already deleted items
                    }
                    // We keep them cached for the current command only
                }


                GitItem pathItem; // We promissed to return an updated item for the specified path; check if we updated it

                if (!_map.TryGetValue(path, out pathItem))
                {
                    // We did not; it does not even exist in the cache
                    StoreItem(pathItem = CreateItem(path, NoSccStatus.NotExisting));

                    if (directory != null)
                    {
                        updateDir.Store(pathItem);
                        ScheduleForCleanup(directory);
                    }
                }
                else
                {
                    IGitItemUpdate update = pathItem;

                    if (!update.IsStatusClean())
                    {
                        update.RefreshTo(NoSccStatus.NotExisting, SvnNodeKind.Unknown); // We did not see it in the walker

                        if (directory != null)
                        {
                            ((IGitDirectoryUpdate)directory).Store(pathItem);
                            ScheduleForCleanup(directory);
                        }
                    }
                }
            }
        }