public Commit(LibGit2Sharp.Commit original) { Id = original.Id; Message = original.Message; Name = original.Author.Name; Files = original.Tree.Select(t => t.Name).ToList(); }
/// <summary> /// Reads the version.txt file that is in the specified commit. /// </summary> /// <param name="commit">The commit to read the version file from.</param> /// <param name="repoRelativeProjectDirectory">The directory to consider when searching for the version.txt file.</param> /// <param name="isJsonFile">Receives a value indicating whether the file found is a JSON file.</param> /// <returns>A text reader with the content of the version.txt file.</returns> private static TextReader GetVersionFileReader(LibGit2Sharp.Commit commit, string repoRelativeProjectDirectory, out bool isJsonFile) { string searchDirectory = repoRelativeProjectDirectory ?? string.Empty; while (searchDirectory != null) { string candidatePath = Path.Combine(searchDirectory, JsonFileName); var versionTxtBlob = commit.Tree[candidatePath]?.Target as LibGit2Sharp.Blob; if (versionTxtBlob != null) { isJsonFile = true; return(new StreamReader(versionTxtBlob.GetContentStream())); } candidatePath = Path.Combine(searchDirectory, TxtFileName); versionTxtBlob = commit.Tree[candidatePath]?.Target as LibGit2Sharp.Blob; if (versionTxtBlob != null) { isJsonFile = false; return(new StreamReader(versionTxtBlob.GetContentStream())); } searchDirectory = searchDirectory.Length > 0 ? Path.GetDirectoryName(searchDirectory) : null; } isJsonFile = false; return(null); }
/// <summary> /// Reads the version.txt file and returns the <see cref="Version"/> and prerelease tag from it. /// </summary> /// <param name="commit">The commit to read the version file from.</param> /// <param name="repoRelativeProjectDirectory">The directory to consider when searching for the version.txt file.</param> /// <returns>The version information read from the file.</returns> public static VersionOptions GetVersion(LibGit2Sharp.Commit commit, string repoRelativeProjectDirectory = null) { if (commit == null) { return(null); } string searchDirectory = repoRelativeProjectDirectory ?? string.Empty; while (searchDirectory != null) { string parentDirectory = searchDirectory.Length > 0 ? Path.GetDirectoryName(searchDirectory) : null; string candidatePath = Path.Combine(searchDirectory, TxtFileName).Replace('\\', '/'); var versionTxtBlob = commit.Tree[candidatePath]?.Target as LibGit2Sharp.Blob; if (versionTxtBlob != null) { var result = TryReadVersionFile(new StreamReader(versionTxtBlob.GetContentStream()), isJsonFile: false); if (result != null) { return(result); } } candidatePath = Path.Combine(searchDirectory, JsonFileName).Replace('\\', '/'); var versionJsonBlob = commit.Tree[candidatePath]?.Target as LibGit2Sharp.Blob; if (versionJsonBlob != null) { string versionJsonContent; using (var sr = new StreamReader(versionJsonBlob.GetContentStream())) { versionJsonContent = sr.ReadToEnd(); } VersionOptions result = TryReadVersionJsonContent(versionJsonContent); if (result?.Inherit ?? false) { if (parentDirectory != null) { result = GetVersion(commit, parentDirectory); if (result != null) { JsonConvert.PopulateObject(versionJsonContent, result, VersionOptions.GetJsonSettings()); return(result); } } throw new InvalidOperationException($"\"{candidatePath}\" inherits from a parent directory version.json file but none exists."); } else if (result != null) { return(result); } } searchDirectory = parentDirectory; } return(null); }
private void OnEnable() { if (window == null) { Init(); } depAnalyzer = new DependencyAnalyzer(); gitAnalyzer = new GitAnalyzer(); verticalSplitView.splitNormalizedPosition = 0.2f; // Create shortened names for commit messages, shown in drop-down menu commitNames = new string[gitAnalyzer.commitList.Count + 1]; commitNames[0] = "NOTHING SELECTED"; for (int i = 0; i < gitAnalyzer.commitList.Count; i++) { LibGit2Sharp.Commit c = gitAnalyzer.commitList[i]; string commitName = (i + 1) + ": [" + c.Author.When.DateTime.ToString("g") + "] (" + c.Author.Name + "): " + c.Message; commitName = commitName.Replace("/", "-"); // The EditorGUILayout.PopUp uses '/' to branch the selection, which I dont want commitName = commitName.Replace("\n", " "); // Newlines cause subsequent options to be pushed down, which I dont want commitName = commitName.Substring(0, Mathf.Min(100, commitName.Length)) + "..."; commitNames[i + 1] = commitName; } commitIndex = 0; typeIndex = 0; hideUnchanged = false; ResetTree(); }
/// <summary> /// Initializes a new instance of the <see cref="VersionOracle"/> class. /// </summary> public VersionOracle(string projectDirectory, LibGit2Sharp.Repository repo, LibGit2Sharp.Commit head, ICloudBuild cloudBuild, int?overrideBuildNumberOffset = null, string projectPathRelativeToGitRepoRoot = null) { var repoRoot = repo?.Info?.WorkingDirectory?.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); var relativeRepoProjectDirectory = !string.IsNullOrWhiteSpace(repoRoot) ? (!string.IsNullOrEmpty(projectPathRelativeToGitRepoRoot) ? projectPathRelativeToGitRepoRoot : projectDirectory.Substring(repoRoot.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)) : null; var commit = head ?? repo?.Head.Commits.FirstOrDefault(); var committedVersion = VersionFile.GetVersion(commit, relativeRepoProjectDirectory); var workingVersion = head != null?VersionFile.GetVersion(head, relativeRepoProjectDirectory) : VersionFile.GetVersion(projectDirectory); if (overrideBuildNumberOffset.HasValue) { if (committedVersion != null) { committedVersion.BuildNumberOffset = overrideBuildNumberOffset.Value; } if (workingVersion != null) { workingVersion.BuildNumberOffset = overrideBuildNumberOffset.Value; } } this.VersionOptions = committedVersion ?? workingVersion; this.GitCommitId = commit?.Id.Sha ?? cloudBuild?.GitCommitId ?? null; this.VersionHeight = CalculateVersionHeight(relativeRepoProjectDirectory, commit, committedVersion, workingVersion); this.BuildingRef = cloudBuild?.BuildingTag ?? cloudBuild?.BuildingBranch ?? repo?.Head.CanonicalName; // Override the typedVersion with the special build number and revision components, when available. if (repo != null) { this.Version = GetIdAsVersion(commit, committedVersion, workingVersion, this.VersionHeight); } else { this.Version = this.VersionOptions?.Version.Version ?? Version0; } this.VersionHeightOffset = this.VersionOptions?.BuildNumberOffsetOrDefault ?? 0; this.PrereleaseVersion = this.ReplaceMacros(this.VersionOptions?.Version?.Prerelease ?? string.Empty); this.CloudBuildNumberOptions = this.VersionOptions?.CloudBuild?.BuildNumberOrDefault ?? VersionOptions.CloudBuildNumberOptions.DefaultInstance; if (!string.IsNullOrEmpty(this.BuildingRef) && this.VersionOptions?.PublicReleaseRefSpec?.Length > 0) { this.PublicRelease = this.VersionOptions.PublicReleaseRefSpec.Any( expr => Regex.IsMatch(this.BuildingRef, expr)); } }
/// <summary> /// Creates a new commit object from the given parameters. /// </summary> /// <param name="repo"></param> /// <param name="commit"></param> /// <param name="tags"> </param> /// <returns></returns> public static Commit Create(LibGit2Sharp.Repository repo, LibGit2Sharp.Commit commit, ObservableCollection <Tag> tags) { var c = new Commit(); // Process Tags (Git tags to display next to the commit description). var commitTags = new ObservableCollection <Tag>(); foreach (var tag in tags) { if (tag.TargetSha == commit.Sha) { commitTags.Add(tag); tag.Target = c; } } // Process display tags. var displayTags = new List <string>(); if (repo.Head.Tip == commit) { displayTags.Add("HEAD"); } // Process ParentHashes. var parentHashes = new List <string>(); foreach (var parentCommit in commit.Parents) { parentHashes.Add(parentCommit.Sha); } // Set properties. c.AuthorEmail = commit.Author.Email; c.AuthorName = commit.Author.Name; c.Date = commit.Author.When.DateTime; c.Description = commit.Message; c.ShortDescription = commit.Message.Right(72).RemoveLineBreaks(); c.DisplayTags = displayTags; c.Branches = new List <Branch>(); c.Tags = commitTags; c.Hash = commit.Sha; c.ParentHashes = parentHashes; c.ParentCount = commit.ParentsCount; c.Parents = new List <Commit>(); c.ObjectId = commit.Id; c.VisualPosition = -1; // -1 means it's not yet calculated. c.Children = new List <Commit>(); return(c); }
/// <summary> /// Reads the version.txt file and returns the <see cref="Version"/> and prerelease tag from it. /// </summary> /// <param name="commit">The commit to read the version file from.</param> /// <param name="repoRelativeProjectDirectory">The directory to consider when searching for the version.txt file.</param> /// <returns>The version information read from the file.</returns> public static SemanticVersion GetVersion(LibGit2Sharp.Commit commit, string repoRelativeProjectDirectory = null) { if (commit == null) { return(null); } using (var content = GetVersionFileReader(commit, repoRelativeProjectDirectory)) { return(content != null ? ReadVersionFile(content) : null); } }
public Commit(LibGit2Sharp.Commit commit) { GitCommit = commit; Sha = string.Join("", commit.Sha); Author = commit.Author.Name; Email = commit.Author.Email; Description = commit.Message; DescriptionShort = commit.MessageShort.Replace("\n", " "); Date = commit.Author.When; Parents = new HashSet <string>(); Base = new Dictionary <int, int>(); foreach (var parent in commit.Parents) { Parents.Add(string.Join("", parent.Sha)); } }
/// <summary> /// Reads the version.txt file and returns the <see cref="Version"/> and prerelease tag from it. /// </summary> /// <param name="commit">The commit to read the version file from.</param> /// <param name="repoRelativeProjectDirectory">The directory to consider when searching for the version.txt file.</param> /// <returns>The version information read from the file.</returns> public static VersionOptions GetVersion(LibGit2Sharp.Commit commit, string repoRelativeProjectDirectory = null) { if (commit == null) { return(null); } bool json; using (var content = GetVersionFileReader(commit, repoRelativeProjectDirectory, out json)) { return(content != null ? TryReadVersionFile(content, json) : null); } }
public static RevisionModel FromCommit(LibGit2Sharp.Commit commit, LibGit2Sharp.TreeEntry entry, ManagedFile file) { var model = new RevisionModel() { CommitterName = commit.Committer.Name, //CommitterEmail = commit.Committer.Email, Timestamp = commit.Committer.When.DateTime, Message = commit.Message, FileId = file.Id, FileName = entry.Name, Commit = commit.Sha, Sha = entry.Target.Sha, FileSize = ((LibGit2Sharp.Blob)entry.Target).Size }; return(model); }
/// <summary> /// Reads the version from a given <c>.sdpkg</c> file in a specific Git commit. /// </summary> /// <param name="commit"><see cref="LibGit2Sharp.Commit"/> in which to look for <paramref cref="packagePath"/>.</param> /// <param name="packagePath">Stride Package file path.</param> /// <returns><see cref="VersionOptions"/> with the Stride Package version.</returns> public static VersionOptions GetVersion(LibGit2Sharp.Commit commit, string packagePath) { if (commit is null) { return(null); } try { if (commit.Tree[packagePath]?.Target is LibGit2Sharp.Blob packageData) { return(GetVersionFromStream(packageData.GetContentStream())); } } catch { } return(null); }
private static Version GetIdAsVersion(LibGit2Sharp.Commit headCommit, VersionOptions committedVersion, VersionOptions workingVersion, int versionHeight) { var version = IsVersionFileChangedInWorkingTree(committedVersion, workingVersion) ? workingVersion : committedVersion; return(headCommit.GetIdAsVersionHelper(version, versionHeight)); }
private static int CalculateVersionHeight(string relativeRepoProjectDirectory, LibGit2Sharp.Commit headCommit, VersionOptions committedVersion, VersionOptions workingVersion) { var headCommitVersion = committedVersion?.Version?.Version ?? Version0; if (IsVersionFileChangedInWorkingTree(committedVersion, workingVersion)) { var workingCopyVersion = workingVersion?.Version?.Version; if (workingCopyVersion == null || !workingCopyVersion.Equals(headCommitVersion)) { // The working copy has changed the major.minor version. // So by definition the version height is 0, since no commit represents it yet. return(0); } } return(headCommit?.GetHeight(c => c.CommitMatchesMajorMinorVersion(headCommitVersion, relativeRepoProjectDirectory)) ?? 0); }
/// <summary> /// Reads the version.txt file and returns the <see cref="Version"/> and prerelease tag from it. /// </summary> /// <param name="commit">The commit to read the version file from.</param> /// <param name="repoRelativeProjectDirectory">The directory to consider when searching for the version.txt file.</param> /// <returns>The version information read from the file.</returns> public static VersionOptions GetVersion(LibGit2Sharp.Commit commit, string repoRelativeProjectDirectory = null) { if (commit == null) { return(null); } string searchDirectory = repoRelativeProjectDirectory ?? string.Empty; while (searchDirectory != null) { string parentDirectory = searchDirectory.Length > 0 ? Path.GetDirectoryName(searchDirectory) : null; string candidatePath = Path.Combine(searchDirectory, TxtFileName).Replace('\\', '/'); var versionTxtBlob = commit.Tree[candidatePath]?.Target as LibGit2Sharp.Blob; if (versionTxtBlob != null) { var result = TryReadVersionFile(new StreamReader(versionTxtBlob.GetContentStream()), isJsonFile: false); if (result != null) { return(result); } } candidatePath = Path.Combine(searchDirectory, JsonFileName).Replace('\\', '/'); var versionJsonBlob = commit.Tree[candidatePath]?.Target as LibGit2Sharp.Blob; if (versionJsonBlob != null) { string versionJsonContent; using (var sr = new StreamReader(versionJsonBlob.GetContentStream())) { versionJsonContent = sr.ReadToEnd(); } VersionOptions result; try { result = TryReadVersionJsonContent(versionJsonContent); } catch (FormatException ex) { throw new FormatException( $"Failure while reading {JsonFileName} from commit {commit.Sha}. " + "Fix this commit with rebase if this is an error, or review this doc on how to migrate to Nerdbank.GitVersioning: " + "https://github.com/AArnott/Nerdbank.GitVersioning/blob/master/doc/migrating.md", ex); } if (result?.Inherit ?? false) { if (parentDirectory != null) { result = GetVersion(commit, parentDirectory); if (result != null) { JsonConvert.PopulateObject(versionJsonContent, result, VersionOptions.GetJsonSettings()); return(result); } } throw new InvalidOperationException($"\"{candidatePath}\" inherits from a parent directory version.json file but none exists."); } else if (result != null) { return(result); } } searchDirectory = parentDirectory; } return(null); }
/// <summary> /// Checks whether the version.txt file is defined in the specified commit. /// </summary> /// <param name="commit">The commit to search.</param> /// <param name="projectDirectory">The directory to consider when searching for the version.txt file.</param> /// <returns><c>true</c> if the version.txt file is found; otherwise <c>false</c>.</returns> public static bool IsVersionDefined(LibGit2Sharp.Commit commit, string projectDirectory = null) { return(GetVersion(commit, projectDirectory) != null); }
/// <summary> /// Initializes a new instance of the <see cref="VersionOracle"/> class. /// </summary> public VersionOracle(string projectDirectory, LibGit2Sharp.Repository repo, LibGit2Sharp.Commit head, ICloudBuild cloudBuild, int?overrideVersionHeightOffset = null, string projectPathRelativeToGitRepoRoot = null) { var relativeRepoProjectDirectory = projectPathRelativeToGitRepoRoot ?? repo?.GetRepoRelativePath(projectDirectory); if (repo is object) { // If we're particularly git focused, normalize/reset projectDirectory to be the path we *actually* want to look at in case we're being redirected. projectDirectory = Path.Combine(repo.Info.WorkingDirectory, relativeRepoProjectDirectory); } var commit = head ?? repo?.Head.Tip; var committedVersion = VersionFile.GetVersion(commit, relativeRepoProjectDirectory); var workingVersion = head is object?VersionFile.GetVersion(head, relativeRepoProjectDirectory) : VersionFile.GetVersion(projectDirectory); if (overrideVersionHeightOffset.HasValue) { if (committedVersion != null) { committedVersion.VersionHeightOffset = overrideVersionHeightOffset.Value; } if (workingVersion != null) { workingVersion.VersionHeightOffset = overrideVersionHeightOffset.Value; } } this.VersionOptions = committedVersion ?? workingVersion; this.GitCommitId = commit?.Id.Sha ?? cloudBuild?.GitCommitId ?? null; this.GitCommitDate = commit?.Author.When; this.VersionHeight = CalculateVersionHeight(relativeRepoProjectDirectory, commit, committedVersion, workingVersion); this.BuildingRef = cloudBuild?.BuildingTag ?? cloudBuild?.BuildingBranch ?? repo?.Head.CanonicalName; // Override the typedVersion with the special build number and revision components, when available. if (repo != null) { this.Version = GetIdAsVersion(commit, committedVersion, workingVersion, this.VersionHeight); } else { this.Version = this.VersionOptions?.Version.Version ?? Version0; } // get the commit id abbreviation only if the commit id is set if (!string.IsNullOrEmpty(this.GitCommitId)) { var gitCommitIdShortFixedLength = this.VersionOptions?.GitCommitIdShortFixedLength ?? VersionOptions.DefaultGitCommitIdShortFixedLength; var gitCommitIdShortAutoMinimum = this.VersionOptions?.GitCommitIdShortAutoMinimum ?? 0; // get it from the git repository if there is a repository present and it is enabled if (repo != null && gitCommitIdShortAutoMinimum > 0) { this.GitCommitIdShort = repo.ObjectDatabase.ShortenObjectId(commit, gitCommitIdShortAutoMinimum); } else { this.GitCommitIdShort = this.GitCommitId.Substring(0, gitCommitIdShortFixedLength); } } this.VersionHeightOffset = this.VersionOptions?.VersionHeightOffsetOrDefault ?? 0; this.PrereleaseVersion = this.ReplaceMacros(this.VersionOptions?.Version?.Prerelease ?? string.Empty); this.CloudBuildNumberOptions = this.VersionOptions?.CloudBuild?.BuildNumberOrDefault ?? VersionOptions.CloudBuildNumberOptions.DefaultInstance; if (!string.IsNullOrEmpty(this.BuildingRef) && this.VersionOptions?.PublicReleaseRefSpec?.Count > 0) { this.PublicRelease = this.VersionOptions.PublicReleaseRefSpec.Any( expr => Regex.IsMatch(this.BuildingRef, expr)); } }
internal Commit(LibGit2Sharp.Commit objectId) { innerObjectId = objectId; }
/// <summary> /// Initializes a new instance of the <see cref="VersionOracle"/> class. /// </summary> public VersionOracle(string projectDirectory, LibGit2Sharp.Repository repo, LibGit2Sharp.Commit head, ICloudBuild cloudBuild, int?overrideVersionHeightOffset = null, string projectPathRelativeToGitRepoRoot = null) { var repoRoot = repo?.Info?.WorkingDirectory?.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && repoRoot != null && repoRoot.StartsWith("\\") && (repoRoot.Length == 1 || repoRoot[1] != '\\')) { // We're in a worktree, which libgit2sharp only gives us as a path relative to the root of the assumed drive. // Add the drive: to the front of the repoRoot. repoRoot = repo.Info.Path.Substring(0, 2) + repoRoot; } var relativeRepoProjectDirectory = !string.IsNullOrWhiteSpace(repoRoot) ? (!string.IsNullOrEmpty(projectPathRelativeToGitRepoRoot) ? projectPathRelativeToGitRepoRoot : projectDirectory.Substring(repoRoot.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)) : null; var commit = head ?? repo?.Head.Tip; var committedVersion = VersionFile.GetVersion(commit, relativeRepoProjectDirectory); var workingVersion = head != null?VersionFile.GetVersion(head, relativeRepoProjectDirectory) : VersionFile.GetVersion(projectDirectory); if (overrideVersionHeightOffset.HasValue) { if (committedVersion != null) { committedVersion.VersionHeightOffset = overrideVersionHeightOffset.Value; } if (workingVersion != null) { workingVersion.VersionHeightOffset = overrideVersionHeightOffset.Value; } } this.VersionOptions = committedVersion ?? workingVersion; this.GitCommitId = commit?.Id.Sha ?? cloudBuild?.GitCommitId ?? null; this.GitCommitDate = commit?.Author.When; this.VersionHeight = CalculateVersionHeight(relativeRepoProjectDirectory, commit, committedVersion, workingVersion); this.BuildingRef = cloudBuild?.BuildingTag ?? cloudBuild?.BuildingBranch ?? repo?.Head.CanonicalName; // Override the typedVersion with the special build number and revision components, when available. if (repo != null) { this.Version = GetIdAsVersion(commit, committedVersion, workingVersion, this.VersionHeight); } else { this.Version = this.VersionOptions?.Version.Version ?? Version0; } // get the commit id abbreviation only if the commit id is set if (!string.IsNullOrEmpty(this.GitCommitId)) { var gitCommitIdShortFixedLength = this.VersionOptions?.GitCommitIdShortFixedLength ?? VersionOptions.DefaultGitCommitIdShortFixedLength; var gitCommitIdShortAutoMinimum = this.VersionOptions?.GitCommitIdShortAutoMinimum ?? 0; // get it from the git repository if there is a repository present and it is enabled if (repo != null && gitCommitIdShortAutoMinimum > 0) { this.GitCommitIdShort = repo.ObjectDatabase.ShortenObjectId(commit, gitCommitIdShortAutoMinimum); } else { this.GitCommitIdShort = this.GitCommitId.Substring(0, gitCommitIdShortFixedLength); } } this.VersionHeightOffset = this.VersionOptions?.VersionHeightOffsetOrDefault ?? 0; this.PrereleaseVersion = this.ReplaceMacros(this.VersionOptions?.Version?.Prerelease ?? string.Empty); this.CloudBuildNumberOptions = this.VersionOptions?.CloudBuild?.BuildNumberOrDefault ?? VersionOptions.CloudBuildNumberOptions.DefaultInstance; if (!string.IsNullOrEmpty(this.BuildingRef) && this.VersionOptions?.PublicReleaseRefSpec?.Length > 0) { this.PublicRelease = this.VersionOptions.PublicReleaseRefSpec.Any( expr => Regex.IsMatch(this.BuildingRef, expr)); } }
public Commit(LibGit2Sharp.Commit commit) : this(commit.Sha, commit.Author.Name, commit.Message) { }
/// <summary> /// Reads the version.json file and returns the <see cref="Version"/> and prerelease tag from it. /// </summary> /// <param name="commit">The commit to read the version file from.</param> /// <param name="repoRelativeProjectDirectory">The directory to consider when searching for the version.txt file.</param> /// <param name="blobVersionCache">An optional blob cache for storing the raw parse results of a version.txt or version.json file (before any inherit merge operations are applied).</param> /// <returns>The version information read from the file.</returns> public static VersionOptions GetVersion(LibGit2Sharp.Commit commit, string repoRelativeProjectDirectory = null, Dictionary <LibGit2Sharp.ObjectId, VersionOptions> blobVersionCache = null) { if (commit == null) { return(null); } string searchDirectory = repoRelativeProjectDirectory ?? string.Empty; while (searchDirectory != null) { string parentDirectory = searchDirectory.Length > 0 ? Path.GetDirectoryName(searchDirectory) : null; string candidatePath = Path.Combine(searchDirectory, TxtFileName).Replace('\\', '/'); var versionTxtBlob = commit.Tree[candidatePath]?.Target as LibGit2Sharp.Blob; if (versionTxtBlob != null) { if (blobVersionCache is null || !blobVersionCache.TryGetValue(versionTxtBlob.Id, out VersionOptions result)) { result = TryReadVersionFile(new StreamReader(versionTxtBlob.GetContentStream())); if (blobVersionCache is object) { result?.Freeze(); blobVersionCache.Add(versionTxtBlob.Id, result); } } if (result != null) { return(result); } } candidatePath = Path.Combine(searchDirectory, JsonFileName).Replace('\\', '/'); var versionJsonBlob = commit.Tree[candidatePath]?.Target as LibGit2Sharp.Blob; if (versionJsonBlob != null) { string versionJsonContent = null; if (blobVersionCache is null || !blobVersionCache.TryGetValue(versionJsonBlob.Id, out VersionOptions result)) { using (var sr = new StreamReader(versionJsonBlob.GetContentStream())) { versionJsonContent = sr.ReadToEnd(); } try { result = TryReadVersionJsonContent(versionJsonContent, searchDirectory); } catch (FormatException ex) { throw new FormatException( $"Failure while reading {JsonFileName} from commit {commit.Sha}. " + "Fix this commit with rebase if this is an error, or review this doc on how to migrate to Nerdbank.GitVersioning: " + "https://github.com/dotnet/Nerdbank.GitVersioning/blob/master/doc/migrating.md", ex); } if (blobVersionCache is object) { result?.Freeze(); blobVersionCache.Add(versionJsonBlob.Id, result); } } if (result?.Inherit ?? false) { if (parentDirectory != null) { result = GetVersion(commit, parentDirectory, blobVersionCache); if (result != null) { if (versionJsonContent is null) { // We reused a cache VersionOptions, but now we need the actual JSON string. using (var sr = new StreamReader(versionJsonBlob.GetContentStream())) { versionJsonContent = sr.ReadToEnd(); } } if (result.IsFrozen) { result = new VersionOptions(result); } JsonConvert.PopulateObject(versionJsonContent, result, VersionOptions.GetJsonSettings(repoRelativeBaseDirectory: searchDirectory)); return(result); } } throw new InvalidOperationException($"\"{candidatePath}\" inherits from a parent directory version.json file but none exists."); } else if (result != null) { return(result); } } searchDirectory = parentDirectory; } return(null); }