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); } } }
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); } } } }
private void DetermineDestinationFolder(string destinationFolderLocation) { var gitDirectory = new GitDirectory(destinationFolderLocation); if (GitProject.IsFolderLocation || DoesSelectedFolderHaveSameNameAsRepo(destinationFolderLocation)) { View.DestinationFolder = destinationFolderLocation; } else { AddRepoNameToDestinationFolder(gitDirectory); } }
private void ScheduleForCleanup(GitDirectory directory) { lock (_lock) { if (!_cleanup.Contains(directory)) { _cleanup.Add(directory); } if (!_postedCleanup) { CommandService.SafePostTickCommand(ref _postedCleanup, AnkhCommand.GitCacheFinishTasks); } } }
private void AddRepoNameToDestinationFolder(GitDirectory gitDirectory) { View.DestinationFolder = string.Format("{0}{1}", gitDirectory.FullName, GitProject.RepostoryName); }
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 }
/// <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); } } } } }
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; }