public async Task <long> GetLatestRevisionAsync(string serverPath, string sourceRevision) { Trace.Verbose($@"Get latest revision of: '{_endpoint.Url.AbsoluteUri}' at or before: '{sourceRevision}'."); string xml = await RunPorcelainCommandAsync( "info", BuildSvnUri(serverPath), "--depth", "empty", "--revision", sourceRevision, "--xml"); // Deserialize the XML. // The command returns a non-zero exit code if the source revision is not found. // The assertions performed here should never fail. XmlSerializer serializer = new XmlSerializer(typeof(SvnInfo)); ArgUtil.NotNullOrEmpty(xml, nameof(xml)); using (StringReader reader = new StringReader(xml)) { SvnInfo info = serializer.Deserialize(reader) as SvnInfo; ArgUtil.NotNull(info, nameof(info)); ArgUtil.NotNull(info.Entries, nameof(info.Entries)); ArgUtil.Equal(1, info.Entries.Length, nameof(info.Entries.Length)); long revision = 0; long.TryParse(info.Entries[0].Commit?.Revision ?? sourceRevision, out revision); return(revision); } }
private async Task <Uri> GetRootUrlAsync(string localPath) { Trace.Verbose($@"Get URL for: '{localPath}'."); try { string xml = await RunPorcelainCommandAsync( "info", localPath, "--depth", "empty", "--xml"); // Deserialize the XML. // The command returns a non-zero exit code if the local path is not a working copy. // The assertions performed here should never fail. XmlSerializer serializer = new XmlSerializer(typeof(SvnInfo)); ArgUtil.NotNullOrEmpty(xml, nameof(xml)); using (StringReader reader = new StringReader(xml)) { SvnInfo info = serializer.Deserialize(reader) as SvnInfo; ArgUtil.NotNull(info, nameof(info)); ArgUtil.NotNull(info.Entries, nameof(info.Entries)); ArgUtil.Equal(1, info.Entries.Length, nameof(info.Entries.Length)); return(new Uri(info.Entries[0].Url)); } } catch (ProcessExitCodeException) { Trace.Verbose($@"The folder '{localPath}.svn' seems not to be a subversion system directory."); return(null); } }
public string ResolveServerPath(string serverPath, string rootPath) { ArgUtil.NotNull(serverPath, nameof(serverPath)); ArgUtil.Equal(true, serverPath.StartsWith(@"^/"), nameof(serverPath)); foreach (string workingDirectoryPath in GetSvnWorkingCopyPaths(rootPath)) { try { Trace.Verbose($@"Get SVN info for the working directory path '{workingDirectoryPath}'."); string xml = RunPorcelainCommandAsync( "info", workingDirectoryPath, "--depth", "empty", "--xml").GetAwaiter().GetResult(); // Deserialize the XML. // The command returns a non-zero exit code if the local path is not a working copy. // The assertions performed here should never fail. XmlSerializer serializer = new XmlSerializer(typeof(SvnInfo)); ArgUtil.NotNullOrEmpty(xml, nameof(xml)); using (StringReader reader = new StringReader(xml)) { SvnInfo info = serializer.Deserialize(reader) as SvnInfo; ArgUtil.NotNull(info, nameof(info)); ArgUtil.NotNull(info.Entries, nameof(info.Entries)); ArgUtil.Equal(1, info.Entries.Length, nameof(info.Entries.Length)); if (serverPath.Equals(info.Entries[0].RelativeUrl, StringComparison.Ordinal) || serverPath.StartsWith(info.Entries[0].RelativeUrl + '/', StringComparison.Ordinal)) { // We've found the mapping the serverPath belongs to. int n = info.Entries[0].RelativeUrl.Length; string relativePath = serverPath.Length <= n + 1 ? string.Empty : serverPath.Substring(n + 1); return(Path.Combine(workingDirectoryPath, relativePath)); } } } catch (ProcessExitCodeException) { Trace.Warning($@"The path '{workingDirectoryPath}' is not an SVN working directory path."); } } Trace.Warning($@"Haven't found any suitable mapping for '{serverPath}'"); // Since the server path starts with the "^/" prefix we return the original path without these two characters. return(serverPath.Substring(2)); }