/// <summary> /// Robustly determines the SVN status of a path using the output of the SVN status command. /// Handles both files and directories, in the case of a directory the status of the directory only, and not all the file-system entries within it. /// Handles warnings by turning them into into the associated <see cref="ItemStatus"/> value. /// Resolves the ambiguous <see cref="ItemStatus.NotFound"/> item status by walking up the path hierarchy until an items status is found. /// </summary> public static SvnStringPathStatus StatusRobust(this SvnCommand svnCommand, AbsolutePath path) { var nonDirectoryIndicatedPath = PathUtilities.EnsurePathIsNotDirectoryIndicated(path.Value).AsAbsolutePath(); var status = svnCommand.StatusRobust_Internal(nonDirectoryIndicatedPath); if (status.ItemStatus != ItemStatus.NotFound) { return(status); } // Determine whether the item is in 1) an ignored directory or 2) an unversioned directory by walking up the path hierarchy until var parentItemStatus = ItemStatus.None; var parentPath = path; do { parentPath = PathUtilities.GetParentDirectoryPath(parentPath); var parentStatus = svnCommand.StatusRobust_Internal(parentPath); parentItemStatus = parentStatus.ItemStatus; }while (parentItemStatus == ItemStatus.NotFound); var output = new SvnStringPathStatus { Path = path.Value, ItemStatus = parentItemStatus }; return(output); }
private static SvnStringPathStatus StatusRobust_Internal(this SvnCommand svnCommand, AbsolutePath absolutePath) { var arguments = SvnCommandServicesProvider.GetStatusVerboseForInstanceOnly(absolutePath) .AddXml(); // Get XML. var outputCollector = SvnCommandServicesProvider.Run(svnCommand.SvnExecutableFilePath, arguments, false); if (outputCollector.AnyError) { var errorText = outputCollector.GetErrorText().Trim(); var notWorkingCopyText = $"svn: warning: W155007: '{absolutePath}' is not a working copy"; if (errorText == notWorkingCopyText) { var output = new SvnStringPathStatus { Path = absolutePath.Value, ItemStatus = ItemStatus.NotWorkingCopy }; return(output); } var notFoundText = $"svn: warning: W155010: The node '{absolutePath}' was not found."; if (errorText == notFoundText) { var output = new SvnStringPathStatus { Path = absolutePath.Value, ItemStatus = ItemStatus.NotFound }; return(output); } throw new Exception($"Unknown SVN error:\n{errorText}"); } var xmlText = outputCollector.GetOutputText(); using (var stream = StreamHelper.FromString(xmlText)) { var xmlStatusType = XmlStreamSerializer.Deserialize <StatusType>(stream, SvnXml.DefaultNamespace); var statuses = SvnCommandServicesProvider.GetStatuses(xmlStatusType); var status = statuses.Count() < 1 ? new SvnStringPathStatus { Path = absolutePath.Value, ItemStatus = ItemStatus.None } : statuses.Single() // Should be only 1. ; return(status); } }