public void GetCommitsFromVersion_WithPathFilters() { string relativeDirectory = "some-sub-dir"; var commitsAt121 = new List <Commit>(); var commitsAt122 = new List <Commit>(); var commitsAt123 = new List <Commit>(); var versionData = VersionOptions.FromVersion(new Version("1.2")); versionData.PathFilters = new[] { new FilterPath("./", relativeDirectory), new FilterPath(":^/some-sub-dir/ignore.txt", relativeDirectory), new FilterPath(":^excluded-dir", relativeDirectory) }; commitsAt121.Add(this.WriteVersionFile(versionData, relativeDirectory)); // Commit touching excluded path does not affect version height var ignoredFilePath = Path.Combine(this.RepoPath, relativeDirectory, "ignore.txt"); File.WriteAllText(ignoredFilePath, "hello"); Commands.Stage(this.LibGit2Repository, ignoredFilePath); commitsAt121.Add(this.LibGit2Repository.Commit("Add excluded file", this.Signer, this.Signer)); // Commit touching both excluded and included path does affect height var includedFilePath = Path.Combine(this.RepoPath, relativeDirectory, "another-file.txt"); File.WriteAllText(includedFilePath, "hello"); File.WriteAllText(ignoredFilePath, "changed"); Commands.Stage(this.LibGit2Repository, includedFilePath); Commands.Stage(this.LibGit2Repository, ignoredFilePath); commitsAt122.Add(this.LibGit2Repository.Commit("Change both excluded and included file", this.Signer, this.Signer)); // Commit touching excluded directory does not affect version height var fileInExcludedDirPath = Path.Combine(this.RepoPath, relativeDirectory, "excluded-dir", "ignore.txt"); Directory.CreateDirectory(Path.GetDirectoryName(fileInExcludedDirPath)); File.WriteAllText(fileInExcludedDirPath, "hello"); Commands.Stage(this.LibGit2Repository, fileInExcludedDirPath); commitsAt122.Add(this.LibGit2Repository.Commit("Add file to excluded dir", this.Signer, this.Signer)); // Commit touching project directory affects version height File.WriteAllText(includedFilePath, "more changes"); Commands.Stage(this.LibGit2Repository, includedFilePath); commitsAt123.Add(this.LibGit2Repository.Commit("Changed included file", this.Signer, this.Signer)); this.Context.RepoRelativeProjectDirectory = relativeDirectory; Assert.Equal( commitsAt121.OrderBy(c => c.Sha), LibGit2GitExtensions.GetCommitsFromVersion(this.Context, new Version(1, 2, 1)).OrderBy(c => c.Sha)); Assert.Equal( commitsAt122.OrderBy(c => c.Sha), LibGit2GitExtensions.GetCommitsFromVersion(this.Context, new Version(1, 2, 2)).OrderBy(c => c.Sha)); Assert.Equal( commitsAt123.OrderBy(c => c.Sha), LibGit2GitExtensions.GetCommitsFromVersion(this.Context, new Version(1, 2, 3)).OrderBy(c => c.Sha)); }
public void GetCommitsFromVersion_MatchesOnEitherEndian() { this.InitializeSourceControl(); Commit commit = this.WriteVersionFile(new VersionOptions { Version = SemanticVersion.Parse("1.2"), GitCommitIdShortAutoMinimum = 4 }); Version originalVersion = new VersionOracle(this.Context).Version; Version swappedEndian = new Version(originalVersion.Major, originalVersion.Minor, originalVersion.Build, BinaryPrimitives.ReverseEndianness((ushort)originalVersion.Revision)); ushort twoBytesFromCommitId = checked ((ushort)originalVersion.Revision); Assert.Contains(commit, LibGit2GitExtensions.GetCommitsFromVersion(this.Context, originalVersion)); Assert.Contains(commit, LibGit2GitExtensions.GetCommitsFromVersion(this.Context, swappedEndian)); }
public void GetCommitsFromVersion_WithMajorMinorChecks() { Commit v1_0_50 = this.WriteVersionFile(new VersionOptions { Version = SemanticVersion.Parse("1.0.50-preview.{height}") }); Commit v1_1_50 = this.WriteVersionFile(new VersionOptions { Version = SemanticVersion.Parse("1.1.50-preview.{height}") }); Assert.Empty(LibGit2GitExtensions.GetCommitsFromVersion(this.Context, new Version(1, 0))); Assert.Empty(LibGit2GitExtensions.GetCommitsFromVersion(this.Context, new Version(1, 0, 49))); Assert.Equal(v1_0_50, Assert.Single(LibGit2GitExtensions.GetCommitsFromVersion(this.Context, new Version(1, 0, 50)))); Assert.Equal(v1_1_50, Assert.Single(LibGit2GitExtensions.GetCommitsFromVersion(this.Context, new Version(1, 1, 50)))); }
[InlineData(50, -2, true)] // force many build number collisions. generally revision will still make them unique, but it *might* collide on occasion. public void GetIdAsVersion_Roundtrip_UnstableOffset(int startingOffset, int offsetStepChange, bool allowCollisions) { var versionOptions = new VersionOptions { Version = SemanticVersion.Parse("1.2"), AssemblyVersion = null, VersionHeightOffset = startingOffset, }; this.WriteVersionFile(versionOptions); Commit[] commits = new Commit[16]; // create enough that statistically we'll likely hit interesting bits as MSB and LSB Version[] versions = new Version[commits.Length]; for (int i = 0; i < commits.Length; i += 2) { versionOptions.VersionHeightOffset += offsetStepChange; commits[i] = this.WriteVersionFile(versionOptions); versions[i] = this.GetVersion(committish: commits[i].Sha); commits[i + 1] = this.LibGit2Repository.Commit($"Commit {i + 1}", this.Signer, this.Signer, new CommitOptions { AllowEmptyCommit = true }); versions[i + 1] = this.GetVersion(committish: commits[i + 1].Sha); this.Logger.WriteLine($"Commit {commits[i].Id.Sha.Substring(0, 8)} as version: {versions[i]}"); this.Logger.WriteLine($"Commit {commits[i + 1].Id.Sha.Substring(0, 8)} as version: {versions[i + 1]}"); // Find the commits we just wrote while they are still at the tip of the branch. var matchingCommits = LibGit2GitExtensions.GetCommitsFromVersion(this.Context, versions[i]); Assert.Contains(commits[i], matchingCommits); matchingCommits = LibGit2GitExtensions.GetCommitsFromVersion(this.Context, versions[i + 1]); Assert.Contains(commits[i + 1], matchingCommits); } // Find all commits (again) now that history has been written. for (int i = 0; i < commits.Length; i++) { var matchingCommits = LibGit2GitExtensions.GetCommitsFromVersion(this.Context, versions[i]).ToList(); Assert.Contains(commits[i], matchingCommits); if (!allowCollisions) { Assert.Single(matchingCommits); } } }
private static int OnGetCommitsCommand(string project, bool quiet, string version) { if (!Version.TryParse(version, out Version parsedVersion)) { Console.Error.WriteLine($"\"{version}\" is not a simple a.b.c[.d] version spec."); return((int)ExitCodes.InvalidVersionSpec); } string searchPath = GetSpecifiedOrCurrentDirectoryPath(project); using var context = (LibGit2Context)GitContext.Create(searchPath, writable: true); if (!context.IsRepository) { Console.Error.WriteLine("No git repo found at or above: \"{0}\"", searchPath); return((int)ExitCodes.NoGitRepo); } var candidateCommits = LibGit2GitExtensions.GetCommitsFromVersion(context, parsedVersion); PrintCommits(quiet, context, candidateCommits); return((int)ExitCodes.OK); }
private static int OnTagCommand(string project, string versionOrRef) { if (string.IsNullOrEmpty(versionOrRef)) { versionOrRef = DefaultRef; } string searchPath = GetSpecifiedOrCurrentDirectoryPath(project); using var context = (LibGit2Context)GitContext.Create(searchPath, writable: true); if (context is null) { Console.Error.WriteLine("No git repo found at or above: \"{0}\"", searchPath); return((int)ExitCodes.NoGitRepo); } var repository = context.Repository; if (!context.TrySelectCommit(versionOrRef)) { if (!Version.TryParse(versionOrRef, out Version parsedVersion)) { Console.Error.WriteLine($"\"{versionOrRef}\" is not a simple a.b.c[.d] version spec or git reference."); return((int)ExitCodes.InvalidVersionSpec); } string repoRelativeProjectDir = GetRepoRelativePath(searchPath, repository); var candidateCommits = LibGit2GitExtensions.GetCommitsFromVersion(context, parsedVersion).ToList(); if (candidateCommits.Count == 0) { Console.Error.WriteLine("No commit with that version found."); return((int)ExitCodes.NoMatchingVersion); } else if (candidateCommits.Count > 1) { PrintCommits(false, context, candidateCommits, includeOptions: true); int selection; do { Console.Write("Enter selection: "); }while (!int.TryParse(Console.ReadLine(), out selection) || selection > candidateCommits.Count || selection < 1); context.TrySelectCommit(candidateCommits[selection - 1].Sha); } else { context.TrySelectCommit(candidateCommits.Single().Sha); } } var oracle = new VersionOracle(context, CloudBuild.Active); if (!oracle.VersionFileFound) { Console.Error.WriteLine("No version.json file found in or above \"{0}\" in commit {1}.", searchPath, context.GitCommitId); return((int)ExitCodes.NoVersionJsonFound); } oracle.PublicRelease = true; // assume a public release so we don't get a redundant -gCOMMITID in the tag name string tagName = $"v{oracle.SemVer2}"; try { context.ApplyTag(tagName); } catch (LibGit2Sharp.NameConflictException) { var taggedCommit = repository.Tags[tagName].Target as LibGit2Sharp.Commit; bool correctTag = taggedCommit?.Sha == context.GitCommitId; Console.Error.WriteLine("The tag {0} is already defined ({1}).", tagName, correctTag ? "to the right commit" : $"expected {context.GitCommitId} but was on {taggedCommit.Sha}"); return((int)(correctTag ? ExitCodes.OK : ExitCodes.TagConflict)); } Console.WriteLine("{0} tag created at {1}.", tagName, context.GitCommitId); Console.WriteLine("Remember to push to a remote: git push origin {0}", tagName); return((int)ExitCodes.OK); }