protected override void Execute(GVFSEnlistment enlistment) { // Now default to the current working directory when running the verb without a specified path if (string.IsNullOrEmpty(this.Directory) || this.Directory.Equals(".")) { if (Environment.CurrentDirectory.StartsWith(enlistment.WorkingDirectoryRoot, StringComparison.OrdinalIgnoreCase)) { this.Directory = Environment.CurrentDirectory.Substring(enlistment.WorkingDirectoryRoot.Length); } else { // If the path is not under the source root, set the directory to empty this.Directory = string.Empty; } } this.Output.WriteLine("\nGathering repository data..."); this.Directory = this.Directory.Replace(GVFSPlatform.GVFSPlatformConstants.PathSeparator, GVFSConstants.GitPathSeparator); EnlistmentPathData pathData = new EnlistmentPathData(); this.GetPlaceholdersFromDatabase(enlistment, pathData); this.GetModifiedPathsFromPipe(enlistment, pathData); this.GetPathsFromGitIndex(enlistment, pathData); pathData.NormalizeAllPaths(); EnlistmentHealthCalculator enlistmentHealthCalculator = new EnlistmentHealthCalculator(pathData); EnlistmentHealthData enlistmentHealthData = enlistmentHealthCalculator.CalculateStatistics(this.Directory); this.PrintOutput(enlistmentHealthData); }
/// <summary> /// Call 'git ls-files' and 'git ls-tree' to get a list of all files and directories in the enlistment /// </summary> /// <param name="enlistment">The current GVFS enlistmetn being operated on</param> /// <param name="pathData">The path data object where paths are being saved</param> private void GetPathsFromGitIndex(GVFSEnlistment enlistment, EnlistmentPathData pathData) { List <string> skipWorktreeFiles = new List <string>(); GitProcess gitProcess = new GitProcess(enlistment); GitProcess.Result fileResult = gitProcess.LsFiles( line => { if (line.First() == 'H') { skipWorktreeFiles.Add(this.TrimGitIndexLineWithSkipWorktree(line)); } pathData.GitFilePaths.Add(this.TrimGitIndexLineWithSkipWorktree(line)); }); GitProcess.Result folderResult = gitProcess.LsTree( GVFSConstants.DotGit.HeadName, line => { pathData.GitFolderPaths.Add(this.TrimGitIndexLine(line)); }, recursive: true, showDirectories: true); pathData.GitTrackingPaths.AddRange(skipWorktreeFiles); }
/// <summary> /// Get two lists of placeholders, one containing the files and the other the directories /// Goes to the SQLite database for the placeholder lists /// </summary> /// <param name="enlistment">The current GVFS enlistment being operated on</param> /// <param name="filePlaceholders">Out parameter where the list of file placeholders will end up</param> /// <param name="folderPlaceholders">Out parameter where the list of folder placeholders will end up</param> private void GetPlaceholdersFromDatabase(GVFSEnlistment enlistment, EnlistmentPathData pathData) { List <IPlaceholderData> filePlaceholders = new List <IPlaceholderData>(); List <IPlaceholderData> folderPlaceholders = new List <IPlaceholderData>(); using (GVFSDatabase database = new GVFSDatabase(new PhysicalFileSystem(), enlistment.EnlistmentRoot, new SqliteDatabase())) { PlaceholderTable placeholderTable = new PlaceholderTable(database); placeholderTable.GetAllEntries(out filePlaceholders, out folderPlaceholders); } pathData.PlaceholderFilePaths.AddRange(filePlaceholders.Select(placeholderData => placeholderData.Path)); pathData.PlaceholderFolderPaths.AddRange(folderPlaceholders.Select(placeholderData => placeholderData.Path)); }
/// <summary> /// Talk to the mount process across the named pipe to get a list of the modified paths /// </summary> /// <remarks>If/when modified paths are moved to SQLite go there instead</remarks> /// <param name="enlistment">The enlistment being operated on</param> /// <returns>An array containing all of the modified paths in string format</returns> private void GetModifiedPathsFromPipe(GVFSEnlistment enlistment, EnlistmentPathData pathData) { using (NamedPipeClient pipeClient = new NamedPipeClient(enlistment.NamedPipeName)) { string[] modifiedPathsList = Array.Empty <string>(); if (!pipeClient.Connect()) { this.ReportErrorAndExit("Unable to connect to GVFS. Try running 'gvfs mount'"); } try { NamedPipeMessages.Message modifiedPathsMessage = new NamedPipeMessages.Message(NamedPipeMessages.ModifiedPaths.ListRequest, NamedPipeMessages.ModifiedPaths.CurrentVersion); pipeClient.SendRequest(modifiedPathsMessage); NamedPipeMessages.Message modifiedPathsResponse = pipeClient.ReadResponse(); if (!modifiedPathsResponse.Header.Equals(NamedPipeMessages.ModifiedPaths.SuccessResult)) { this.Output.WriteLine("Bad response from modified path pipe: " + modifiedPathsResponse.Header); return; } modifiedPathsList = modifiedPathsResponse.Body.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries); } catch (BrokenPipeException e) { this.ReportErrorAndExit("Unable to communicate with GVFS: " + e.ToString()); } foreach (string path in modifiedPathsList) { if (path.Last() == GVFSConstants.GitPathSeparator) { path.TrimEnd(GVFSConstants.GitPathSeparator); pathData.ModifiedFolderPaths.Add(path); } else { pathData.ModifiedFilePaths.Add(path); } } } }
private EnlistmentHealthData GenerateStatistics(EnlistmentPathData pathData, string directory) { this.enlistmentHealthCalculator = new EnlistmentHealthCalculator(pathData); return(this.enlistmentHealthCalculator.CalculateStatistics(directory)); }