예제 #1
0
        public GitDirectory GetDirectory(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }

            lock (_lock)
            {
                GitDirectory dir;

                if (_dirMap.TryGetValue(path, out dir))
                {
                    return(dir);
                }

                GitItem item = this[path];

                if (item.IsDirectory)
                {
                    dir = new GitDirectory(Context, path);
                    dir.Add(item);
                    return(dir);
                }
                else
                {
                    return(null);
                }
            }
        }
예제 #2
0
        internal void OnCleanup()
        {
            lock (_lock)
            {
                _postedCleanup = false;

                while (_cleanup.Count > 0)
                {
                    GitDirectory dir  = _cleanup[0];
                    string       path = dir.FullPath;

                    _cleanup.RemoveAt(0);

                    for (int i = 0; i < dir.Count; i++)
                    {
                        GitItem item = dir[i];
                        if (((IGitItemUpdate)item).ShouldClean())
                        {
                            RemoveItem(item);
                            dir.RemoveAt(i--);
                        }
                    }

                    if (dir.Count == 0)
                    {
                        // We cache the path before.. as we don't want the Gititem to be generated again
                        _dirMap.Remove(path);
                    }
                }
            }
        }
예제 #3
0
        private void DetermineDestinationFolder(string destinationFolderLocation)
        {
            var gitDirectory = new GitDirectory(destinationFolderLocation);

            if (GitProject.IsFolderLocation || DoesSelectedFolderHaveSameNameAsRepo(destinationFolderLocation))
            {
                View.DestinationFolder = destinationFolderLocation;
            }
            else
            {
                AddRepoNameToDestinationFolder(gitDirectory);
            }
        }
예제 #4
0
        private void ScheduleForCleanup(GitDirectory directory)
        {
            lock (_lock)
            {
                if (!_cleanup.Contains(directory))
                {
                    _cleanup.Add(directory);
                }

                if (!_postedCleanup)
                {
                    CommandService.SafePostTickCommand(ref _postedCleanup, AnkhCommand.GitCacheFinishTasks);
                }
            }
        }
예제 #5
0
 private void AddRepoNameToDestinationFolder(GitDirectory gitDirectory)
 {
     View.DestinationFolder = string.Format("{0}{1}", gitDirectory.FullName, GitProject.RepostoryName);
 }
예제 #6
0
        private void StatDirectory(string walkPath, GitDirectory directory, bool noWcAtAll)
        {
            // Note: There is a lock(_lock) around this in our caller

            bool        canRead;
            string      adminName   = GitClient.AdministrativeDirectoryName;
            NoSccStatus noSccStatus = noWcAtAll ? NoSccStatus.NotVersionable : NoSccStatus.NotVersioned;

            foreach (SccFileSystemNode node in SccFileSystemNode.GetDirectoryNodes(walkPath, out canRead))
            {
                if (string.Equals(node.Name, adminName, StringComparison.OrdinalIgnoreCase) || node.IsHiddenOrSystem)
                {
                    continue;
                }

                GitItem item;
                if (node.IsFile)
                {
                    if (!_map.TryGetValue(node.FullPath, out item))
                    {
                        StoreItem(CreateItem(node.FullPath, noSccStatus, SvnNodeKind.File));
                    }
                    else
                    {
                        IGitItemUpdate updateItem = item;
                        if (updateItem.ShouldRefresh())
                        {
                            updateItem.RefreshTo(noSccStatus, SvnNodeKind.File);
                        }
                    }
                }
                else
                {
                    if (!_map.TryGetValue(node.FullPath, out item))
                    {
                        StoreItem(CreateItem(node.FullPath, noSccStatus, SvnNodeKind.Directory));
                    }
                    // Don't clear state of a possible working copy
                }
            }

            if (canRead) // The directory exists
            {
                GitItem item;

                if (!_map.TryGetValue(walkPath, out item))
                {
                    StoreItem(CreateItem(walkPath, NoSccStatus.NotVersioned, SvnNodeKind.Directory));
                    // Mark it as existing if we are sure
                }
                else
                {
                    IGitItemUpdate updateItem = item;
                    if (updateItem.ShouldRefresh())
                    {
                        updateItem.RefreshTo(NoSccStatus.NotVersioned, SvnNodeKind.Directory);
                    }
                }
            }

            // Note: There is a lock(_lock) around this in our caller
        }
예제 #7
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);
                        }
                    }
                }
            }
        }
예제 #8
0
        private void DetermineDestinationFolder(string destinationFolderLocation)
        {
            var gitDirectory = new GitDirectory(destinationFolderLocation);

            if (GitProject.IsFolderLocation || DoesSelectedFolderHaveSameNameAsRepo(destinationFolderLocation))
            {
                View.DestinationFolder = destinationFolderLocation;
            }
            else
            {
                AddRepoNameToDestinationFolder(gitDirectory);
            }
        }
예제 #9
0
 private void AddRepoNameToDestinationFolder(GitDirectory gitDirectory)
 {
     View.DestinationFolder = string.Format("{0}{1}", gitDirectory.FullName, GitProject.RepostoryName);
 }
        IDictionary<string, string> LoadSnapshotIds()
        {
            var result = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
            
            var files = new GitDirectory(null, "root", m_Commit)
                .GetDirectory(s_SnapshotDirectoryName)
                .Files
                .Where(f => f.Name.EndsWith(s_FileNameSuffix, StringComparison.InvariantCultureIgnoreCase))
                .Cast<IReadableFile>();

            foreach (var file in files)
            {
                var textFile = TextFile.Load(null, file);

                var historyName = file.Name.Replace(s_FileNameSuffix, "");
                var snapshotId = String.IsNullOrEmpty(textFile.Content) ? null : textFile.Content;

                result.Add(historyName, snapshotId);                
            }

            return result;
        }