diff --git a/.gitignore b/.gitignore index 22ffac1..ccdbe01 100644 --- a/.gitignore +++ b/.gitignore @@ -41,7 +41,6 @@ dlldata.c # DNX project.lock.json -artifacts/ *_i.c *_p.c diff --git a/FSharp.GitReader.Tests/PrimitiveRepositoryTests.GetBranchHeads.verified.txt b/FSharp.GitReader.Tests/PrimitiveRepositoryTests.GetBranchHeads.verified.txt index 0efe4e9..b4e35cf 100644 --- a/FSharp.GitReader.Tests/PrimitiveRepositoryTests.GetBranchHeads.verified.txt +++ b/FSharp.GitReader.Tests/PrimitiveRepositoryTests.GetBranchHeads.verified.txt @@ -1,6 +1,7 @@ [ { Name: master, + RelativePath: refs/heads/master, Target: { HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 } diff --git a/FSharp.GitReader.Tests/PrimitiveRepositoryTests.GetRemoteBranchHeads.verified.txt b/FSharp.GitReader.Tests/PrimitiveRepositoryTests.GetRemoteBranchHeads.verified.txt index 437cd7a..15ee484 100644 --- a/FSharp.GitReader.Tests/PrimitiveRepositoryTests.GetRemoteBranchHeads.verified.txt +++ b/FSharp.GitReader.Tests/PrimitiveRepositoryTests.GetRemoteBranchHeads.verified.txt @@ -1,36 +1,49 @@ [ { Name: origin/HEAD, + RelativePath: refs/remotes/origin/HEAD, Target: { - HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + HashCode: 1a85b097bde6e9800a1700f702202b3f232c8bda } }, { Name: origin/appveyor, + RelativePath: refs/remotes/origin/appveyor, Target: { HashCode: 0a064ec9cd2199e1ecf879496b55d5e956e546ac } }, { Name: origin/devel, + RelativePath: refs/remotes/origin/devel, Target: { HashCode: f2f51b6fe6076ca630ca66c5c9f451217762652a } }, + { + Name: origin/develop, + RelativePath: refs/remotes/origin/develop, + Target: { + HashCode: d1e1a7d34cadde9a4cd3579a7f676180549677ca + } + }, { Name: origin/expression-tree, + RelativePath: refs/remotes/origin/expression-tree, Target: { HashCode: d449e3191e52be96c29ef47992a3bf78b0c759b1 } }, { Name: origin/master, + RelativePath: refs/remotes/origin/master, Target: { - HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + HashCode: 1a85b097bde6e9800a1700f702202b3f232c8bda } }, { Name: origin/netcore, + RelativePath: refs/remotes/origin/netcore, Target: { HashCode: f690f0e7bf703582a1fad7e6f1c2d1586390f43d } diff --git a/FSharp.GitReader.Tests/PrimitiveRepositoryTests.GetTags.verified.txt b/FSharp.GitReader.Tests/PrimitiveRepositoryTests.GetTags.verified.txt index 8604ec5..5bc3c2a 100644 --- a/FSharp.GitReader.Tests/PrimitiveRepositoryTests.GetTags.verified.txt +++ b/FSharp.GitReader.Tests/PrimitiveRepositoryTests.GetTags.verified.txt @@ -138,5 +138,12 @@ }, Type: Commit, Name: 2.1.0 + }, + { + Hash: { + HashCode: 63a8f2c84a8c1b2cf6eabd3e1bd7f1971b912a91 + }, + Type: Commit, + Name: 2.2.0 } ] \ No newline at end of file diff --git a/FSharp.GitReader.Tests/StructuredRepositoryTests.GetBranch.verified.txt b/FSharp.GitReader.Tests/StructuredRepositoryTests.GetBranch.verified.txt index 0539057..775aa12 100644 --- a/FSharp.GitReader.Tests/StructuredRepositoryTests.GetBranch.verified.txt +++ b/FSharp.GitReader.Tests/StructuredRepositoryTests.GetBranch.verified.txt @@ -18,14 +18,6 @@ }, Subject: Added installation .NET 6 SDK on GitHub Actions., Body: , - Branches: [], - RemoteBranches: [ - { - Name: origin/HEAD - }, - { - Name: origin/master - } - ] + Branches: [] } } \ No newline at end of file diff --git a/FSharp.GitReader.Tests/StructuredRepositoryTests.GetBranchesFromCommit.verified.txt b/FSharp.GitReader.Tests/StructuredRepositoryTests.GetBranchesFromCommit.verified.txt index 427b7ce..230e485 100644 --- a/FSharp.GitReader.Tests/StructuredRepositoryTests.GetBranchesFromCommit.verified.txt +++ b/FSharp.GitReader.Tests/StructuredRepositoryTests.GetBranchesFromCommit.verified.txt @@ -19,15 +19,7 @@ }, Subject: Added installation .NET 6 SDK on GitHub Actions., Body: , - Branches: [], - RemoteBranches: [ - { - Name: origin/HEAD - }, - { - Name: origin/master - } - ] + Branches: [] } } ] \ No newline at end of file diff --git a/FSharp.GitReader.Tests/StructuredRepositoryTests.GetCurrentHead.verified.txt b/FSharp.GitReader.Tests/StructuredRepositoryTests.GetCurrentHead.verified.txt index 1815a4c..28a2406 100644 --- a/FSharp.GitReader.Tests/StructuredRepositoryTests.GetCurrentHead.verified.txt +++ b/FSharp.GitReader.Tests/StructuredRepositoryTests.GetCurrentHead.verified.txt @@ -22,14 +22,6 @@ { Name: master } - ], - RemoteBranches: [ - { - Name: origin/HEAD - }, - { - Name: origin/master - } ] } } \ No newline at end of file diff --git a/FSharp.GitReader.Tests/StructuredRepositoryTests.TraverseBranchCommits.verified.txt b/FSharp.GitReader.Tests/StructuredRepositoryTests.TraverseBranchCommits.verified.txt index a929333..ccf9691 100644 --- a/FSharp.GitReader.Tests/StructuredRepositoryTests.TraverseBranchCommits.verified.txt +++ b/FSharp.GitReader.Tests/StructuredRepositoryTests.TraverseBranchCommits.verified.txt @@ -21,14 +21,6 @@ { Name: master } - ], - RemoteBranches: [ - { - Name: origin/HEAD - }, - { - Name: origin/master - } ] }, { diff --git a/GitReader.Core/GitReader.Core.csproj b/GitReader.Core/GitReader.Core.csproj index f85168f..a02da38 100644 --- a/GitReader.Core/GitReader.Core.csproj +++ b/GitReader.Core/GitReader.Core.csproj @@ -27,6 +27,13 @@ + + + all + runtime; build; native; contentfiles; analyzers + + + diff --git a/GitReader.Core/Internal/RepositoryAccessor.cs b/GitReader.Core/Internal/RepositoryAccessor.cs index a0235ac..ab13f6f 100644 --- a/GitReader.Core/Internal/RepositoryAccessor.cs +++ b/GitReader.Core/Internal/RepositoryAccessor.cs @@ -29,22 +29,30 @@ internal enum ReferenceTypes internal readonly struct ReferenceCache { + public readonly ReadOnlyDictionary Branches; public readonly ReadOnlyDictionary RemoteBranches; public readonly ReadOnlyDictionary Tags; public ReferenceCache( + ReadOnlyDictionary branches, ReadOnlyDictionary remoteBranches, ReadOnlyDictionary tags) { + this.Branches = branches; this.RemoteBranches = remoteBranches; this.Tags = tags; } public ReferenceCache Combine(ReferenceCache rhs) { + var branches = this.RemoteBranches.Clone(); var remoteBranches = this.RemoteBranches.Clone(); var tags = this.Tags.Clone(); - + + foreach (var entry in rhs.Branches) + { + branches[entry.Key] = entry.Value; + } foreach (var entry in rhs.RemoteBranches) { remoteBranches[entry.Key] = entry.Value; @@ -54,7 +62,7 @@ public ReferenceCache Combine(ReferenceCache rhs) tags[entry.Key] = entry.Value; } - return new(remoteBranches, tags); + return new(branches, remoteBranches, tags); } } @@ -162,13 +170,13 @@ public static async Task ReadFetchHeadsAsync( var path = Utilities.Combine(repository.GitPath, "FETCH_HEAD"); if (!File.Exists(path)) { - return new(new(new()), new(new())); + return new(new(new()), new(new()), new(new())); } using var fs = repository.fileAccessor.Open(path); var tr = new StreamReader(fs, Encoding.UTF8, true); - var branches = new Dictionary(); + var remoteBranches = new Dictionary(); var tags = new Dictionary(); while (true) @@ -223,7 +231,7 @@ public static async Task ReadFetchHeadsAsync( var urlString = descriptorString.Split(' ').Last(); if (remoteNameByUrl.TryGetValue(urlString, out var remoteName)) { - branches[$"{remoteName}/{name}"] = hash; + remoteBranches[$"{remoteName}/{name}"] = hash; } } else @@ -235,7 +243,7 @@ public static async Task ReadFetchHeadsAsync( { if (typeString == "branch") { - branches[descriptorString] = hash; + remoteBranches[descriptorString] = hash; } else { @@ -244,7 +252,7 @@ public static async Task ReadFetchHeadsAsync( } } - return new(branches, tags); + return new(new(new()), remoteBranches, tags); } public static async Task ReadPackedRefsAsync( @@ -254,13 +262,14 @@ public static async Task ReadPackedRefsAsync( var path = Utilities.Combine(repository.GitPath, "packed-refs"); if (!File.Exists(path)) { - return new(new(new()), new(new())); + return new(new(new()), new(new()), new(new())); } using var fs = repository.fileAccessor.Open(path); var tr = new StreamReader(fs, Encoding.UTF8, true); var branches = new Dictionary(); + var remoteBranches = new Dictionary(); var tags = new Dictionary(); var separators = new[] { ' ' }; @@ -297,17 +306,22 @@ public static async Task ReadPackedRefsAsync( var referenceString = columns[1]; if (referenceString.StartsWith("refs/remotes/")) { - var name = referenceString.Substring(13); + var name = referenceString.Substring("refs/remotes/".Length); + remoteBranches[name] = hash; + } + else if (referenceString.StartsWith("refs/heads/")) + { + var name = referenceString.Substring("refs/heads/".Length); branches[name] = hash; } else if (referenceString.StartsWith("refs/tags/")) { - var name = referenceString.Substring(10); + var name = referenceString.Substring("refs/tags/".Length); tags[name] = hash; } } - return new(branches, tags); + return new(branches, remoteBranches, tags); } ////////////////////////////////////////////////////////////////////////// @@ -370,6 +384,41 @@ public static async Task ReadPackedRefsAsync( } } + public static Task ReadStashesAsync(Repository repository, CancellationToken ct) + => ReadRefLogAsync(repository, "refs/stash", ct); + + public static Task ReadRefLogAsync(Repository repository, PrimitiveReference reference, CancellationToken ct) + => ReadRefLogAsync(repository, reference.RelativePath, ct); + + public static async Task ReadRefLogAsync(Repository repository, string refRelativePath, CancellationToken ct) + { + var path = Utilities.Combine(repository.GitPath, "logs", refRelativePath); + if (!File.Exists(path)) + { + return new PrimitiveRefLogEntry[]{}; + } + + using var fs = repository.fileAccessor.Open(path); + var tr = new StreamReader(fs, Encoding.UTF8, true); + + var entries = new List(); + while (true) + { + var line = await tr.ReadLineAsync().WaitAsync(ct); + if (line == null) + { + break; + } + + if (PrimitiveRefLogEntry.TryParse(line, out var refLogEntry)) + { + entries.Add(refLogEntry); + } + } + + return entries.ToArray(); + } + public static async Task ReadReferencesAsync( Repository repository, ReferenceTypes type, @@ -392,6 +441,7 @@ public static async Task ReadReferencesAsync( { return new( path.Substring(headsPath.Length + 1).Replace(Path.DirectorySeparatorChar, '/'), + path.Substring(repository.GitPath.Length + 1).Replace(Path.DirectorySeparatorChar, '/'), results.Hash); } }))). @@ -399,9 +449,20 @@ public static async Task ReadReferencesAsync( ToDictionary(reference => reference.Name); // Remote branches and tags may not all be placed in `refs/*/`. - // Therefore, information obtained from FETCH_HEAD is also covered. + // Therefore, information obtained from FETCH_HEAD and packed-refs is also covered. switch (type) { + case ReferenceTypes.Branches: + foreach (var entry in repository.referenceCache.Branches) + { + if (!references.ContainsKey(entry.Key)) + { + references.Add( + entry.Key, + new(entry.Key,$"refs/heads/{entry.Key}", entry.Value)); + } + } + break; case ReferenceTypes.RemoteBranches: foreach (var entry in repository.referenceCache.RemoteBranches) { @@ -409,7 +470,7 @@ public static async Task ReadReferencesAsync( { references.Add( entry.Key, - new(entry.Key, entry.Value)); + new(entry.Key,$"refs/remotes/{entry.Key}", entry.Value)); } } break; @@ -420,7 +481,7 @@ public static async Task ReadReferencesAsync( { references.Add( entry.Key, - new(entry.Key, entry.Value)); + new(entry.Key, $"refs/tags/{entry.Key}", entry.Value)); } } break; diff --git a/GitReader.Core/Primitive/PrimitiveRefLogEntry.cs b/GitReader.Core/Primitive/PrimitiveRefLogEntry.cs new file mode 100644 index 0000000..248c376 --- /dev/null +++ b/GitReader.Core/Primitive/PrimitiveRefLogEntry.cs @@ -0,0 +1,88 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +namespace GitReader.Primitive; + +public class PrimitiveRefLogEntry : IEquatable +{ + public readonly Hash Old; + public readonly Hash Current; + public readonly Signature Committer; + public readonly string Message; + + private PrimitiveRefLogEntry(Hash old, Hash current, Signature committer, string message) + { + Old = old; + Current = current; + Committer = committer; + Message = message; + } + + public static bool TryParse(string line, [NotNullWhen(true)]out PrimitiveRefLogEntry? refLogEntry) + { + if (string.IsNullOrEmpty(line)) + { + refLogEntry = null; + return false; + } + + var columns = line.Split('\t'); + if (columns.Length < 2) + { + refLogEntry = null; + return false; + } + + const int hashLength = 40; + + if (!Hash.TryParse(columns[0].Substring(0, hashLength), out var old)) + { + refLogEntry = null; + return false; + } + + if (!Hash.TryParse(columns[0].Substring(hashLength + 1, hashLength), out var current)) + { + refLogEntry = null; + return false; + } + + if (!Signature.TryParse(columns[0].Substring((hashLength + 1) * 2), out var committer)) + { + refLogEntry = null; + return false; + } + + var message = columns[1].Trim(); + + refLogEntry = new PrimitiveRefLogEntry(old, current, committer, message); + return true; + } + + public bool Equals(PrimitiveRefLogEntry? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Old.Equals(other.Old) && Current.Equals(other.Current) && Committer.Equals(other.Committer) && Message == other.Message; + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((PrimitiveRefLogEntry)obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = Old.GetHashCode(); + hashCode = (hashCode * 397) ^ Current.GetHashCode(); + hashCode = (hashCode * 397) ^ Committer.GetHashCode(); + hashCode = (hashCode * 397) ^ Message.GetHashCode(); + return hashCode; + } + } +} \ No newline at end of file diff --git a/GitReader.Core/Primitive/PrimitiveReference.cs b/GitReader.Core/Primitive/PrimitiveReference.cs index 1d5cb65..d14b63a 100644 --- a/GitReader.Core/Primitive/PrimitiveReference.cs +++ b/GitReader.Core/Primitive/PrimitiveReference.cs @@ -12,13 +12,16 @@ namespace GitReader.Primitive; public readonly struct PrimitiveReference { public readonly string Name; + public readonly string RelativePath; public readonly Hash Target; public PrimitiveReference( string name, + string relativePath, Hash target) { this.Name = name; + this.RelativePath = relativePath; this.Target = target; } diff --git a/GitReader.Core/Primitive/RepositoryFacade.cs b/GitReader.Core/Primitive/RepositoryFacade.cs index aa40244..d5b05d2 100644 --- a/GitReader.Core/Primitive/RepositoryFacade.cs +++ b/GitReader.Core/Primitive/RepositoryFacade.cs @@ -58,10 +58,11 @@ public static async Task OpenPrimitiveAsync( Repository repository, CancellationToken ct) { + var relativePathOrLocation = "HEAD"; var results = await RepositoryAccessor.ReadHashAsync( - repository, "HEAD", ct); + repository, relativePathOrLocation, ct); return results is { } r ? - new PrimitiveReference(r.Names.Last(), r.Hash) : + new PrimitiveReference(r.Names.Last(), relativePathOrLocation, r.Hash) : null; } @@ -70,10 +71,11 @@ public static async Task GetBranchHeadReferenceAsync( string branchName, CancellationToken ct) { + var relativePathOrLocation = $"refs/heads/{branchName}"; var results = await RepositoryAccessor.ReadHashAsync( - repository, $"refs/heads/{branchName}", ct); + repository, relativePathOrLocation, ct); return results is { } r ? - new PrimitiveReference(branchName, r.Hash) : + new PrimitiveReference(branchName, relativePathOrLocation, r.Hash) : throw new ArgumentException($"Could not find a branch: {branchName}"); } @@ -81,10 +83,11 @@ public static async Task GetRemoteBranchHeadReferenceAsync( Repository repository, string branchName, CancellationToken ct) { + var relativePathOrLocation = $"refs/remotes/{branchName}"; var results = await RepositoryAccessor.ReadHashAsync( - repository, $"refs/remotes/{branchName}", ct); + repository, relativePathOrLocation, ct); return results is { } r ? - new PrimitiveReference(branchName, r.Hash) : + new PrimitiveReference(branchName, relativePathOrLocation, r.Hash) : throw new ArgumentException($"Could not find a remote branch: {branchName}"); } @@ -92,10 +95,11 @@ public static async Task GetTagReferenceAsync( Repository repository, string tagName, CancellationToken ct) { + var relativePathOrLocation = $"refs/tags/{tagName}"; var results = await RepositoryAccessor.ReadHashAsync( - repository, $"refs/tags/{tagName}", ct); + repository, relativePathOrLocation, ct); return results is { } r ? - new PrimitiveReference(tagName, r.Hash) : + new PrimitiveReference(tagName, relativePathOrLocation, r.Hash) : throw new ArgumentException($"Could not find a tag: {tagName}"); } } diff --git a/GitReader.Core/Structures/RefLogEntry.cs b/GitReader.Core/Structures/RefLogEntry.cs new file mode 100644 index 0000000..8dab799 --- /dev/null +++ b/GitReader.Core/Structures/RefLogEntry.cs @@ -0,0 +1,46 @@ +using System; + +namespace GitReader.Structures; + +public class RefLogEntry : IEquatable +{ + public readonly Commit Commit; + public readonly Commit OldCommit; + public readonly Signature Committer; + public readonly string Message; + + public RefLogEntry(Commit commit, Commit oldCommit, Signature committer, string message) + { + Commit = commit; + OldCommit = oldCommit; + Committer = committer; + Message = message; + } + + public bool Equals(RefLogEntry? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Commit.Equals(other.Commit) && OldCommit.Equals(other.OldCommit) && Committer.Equals(other.Committer) && Message == other.Message; + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((RefLogEntry)obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = Commit.GetHashCode(); + hashCode = (hashCode * 397) ^ OldCommit.GetHashCode(); + hashCode = (hashCode * 397) ^ Committer.GetHashCode(); + hashCode = (hashCode * 397) ^ Message.GetHashCode(); + return hashCode; + } + } +} \ No newline at end of file diff --git a/GitReader.Core/Structures/RepositoryFacade.cs b/GitReader.Core/Structures/RepositoryFacade.cs index 14619cd..11e5eed 100644 --- a/GitReader.Core/Structures/RepositoryFacade.cs +++ b/GitReader.Core/Structures/RepositoryFacade.cs @@ -145,6 +145,45 @@ private static async Task> GetStructuredTagsAsyn DistinctBy(tag => tag!.Name). ToDictionary(tag => tag!.Name, tag => tag!); } + + private static async Task GetStashesAsync( + StructuredRepository repository, + WeakReference rwr, + CancellationToken ct) + { + var primitiveStashes = await RepositoryAccessor.ReadStashesAsync(repository, ct); + var stashes = await Utilities.WhenAll( + primitiveStashes.Select(async stash => + { + if (await RepositoryAccessor.ReadCommitAsync(repository, stash.Current, ct) is { } commit) + { + return new Stash(new (rwr, commit), stash.Committer, stash.Message); + } + return null; + })); + + return stashes.Where(x => x != null).Reverse().ToArray()!; + } + + public static async Task GetHeadRefLogAsync( + StructuredRepository repository, + WeakReference rwr, + CancellationToken ct) + { + var primitiveRefLogEntries = await RepositoryAccessor.ReadRefLogAsync(repository, "HEAD", ct); + var refLogEntries = await Utilities.WhenAll( + primitiveRefLogEntries.Select(async stash => + { + if (await RepositoryAccessor.ReadCommitAsync(repository, stash.Current, ct) is { } currentCommit && + await RepositoryAccessor.ReadCommitAsync(repository, stash.Old, ct) is { } oldCommit) + { + return new RefLogEntry(new (rwr, currentCommit), new (rwr, oldCommit), stash.Committer, stash.Message); + } + return null; + })); + + return refLogEntries.Where(x => x != null).Reverse().ToArray()!; + } ////////////////////////////////////////////////////////////////////////// @@ -175,16 +214,18 @@ public static async Task OpenStructuredAsync( // Read all other requirements. var rwr = new WeakReference(repository); - var (head, branches, remoteBranches, tags) = await Utilities.Join( + var (head, branches, remoteBranches, tags, stashes) = await Utilities.Join( GetCurrentHeadAsync(repository, ct), GetStructuredBranchesAsync(repository, rwr, ct), GetStructuredRemoteBranchesAsync(repository, rwr, ct), - GetStructuredTagsAsync(repository, rwr, ct)); + GetStructuredTagsAsync(repository, rwr, ct), + GetStashesAsync(repository, rwr, ct)); repository.head = head; repository.branches = branches; repository.remoteBranches = remoteBranches; repository.tags = tags; + repository.stashes = stashes; return repository; } diff --git a/GitReader.Core/Structures/Stash.cs b/GitReader.Core/Structures/Stash.cs new file mode 100644 index 0000000..09c5156 --- /dev/null +++ b/GitReader.Core/Structures/Stash.cs @@ -0,0 +1,43 @@ +using System; + +namespace GitReader.Structures; + +public class Stash : IEquatable +{ + public readonly Commit Commit; + public readonly Signature Committer; + public readonly string Message; + + public Stash(Commit commit, Signature committer, string message) + { + Commit = commit; + Committer = committer; + Message = message; + } + + public bool Equals(Stash? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Commit.Equals(other.Commit) && Committer.Equals(other.Committer) && Message == other.Message; + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((Stash)obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = Commit.GetHashCode(); + hashCode = (hashCode * 397) ^ Committer.GetHashCode(); + hashCode = (hashCode * 397) ^ Message.GetHashCode(); + return hashCode; + } + } +} \ No newline at end of file diff --git a/GitReader.Core/Structures/StructuredRepository.cs b/GitReader.Core/Structures/StructuredRepository.cs index c584f8f..3e63561 100644 --- a/GitReader.Core/Structures/StructuredRepository.cs +++ b/GitReader.Core/Structures/StructuredRepository.cs @@ -17,6 +17,7 @@ public sealed class StructuredRepository : Repository internal ReadOnlyDictionary branches = null!; internal ReadOnlyDictionary remoteBranches = null!; internal ReadOnlyDictionary tags = null!; + internal Stash[] stashes = null!; internal StructuredRepository( string repositoryPath) : @@ -29,5 +30,7 @@ internal StructuredRepository( public ReadOnlyDictionary RemoteBranches => this.remoteBranches; public ReadOnlyDictionary Tags => - this.tags; + this.tags; + public Stash[] Stashes => + this.stashes; } diff --git a/GitReader.Tests/Primitive/RepositoryTests.GetBranchHeads.verified.txt b/GitReader.Tests/Primitive/RepositoryTests.GetBranchHeads.verified.txt index 0efe4e9..b4e35cf 100644 --- a/GitReader.Tests/Primitive/RepositoryTests.GetBranchHeads.verified.txt +++ b/GitReader.Tests/Primitive/RepositoryTests.GetBranchHeads.verified.txt @@ -1,6 +1,7 @@ [ { Name: master, + RelativePath: refs/heads/master, Target: { HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 } diff --git a/GitReader.Tests/Primitive/RepositoryTests.GetHeadRefLog.verified.txt b/GitReader.Tests/Primitive/RepositoryTests.GetHeadRefLog.verified.txt new file mode 100644 index 0000000..f65559f --- /dev/null +++ b/GitReader.Tests/Primitive/RepositoryTests.GetHeadRefLog.verified.txt @@ -0,0 +1,149 @@ +[ + { + Current: { + HashCode: cb9b168ff973ce766d55e8697b3aea2c93ad3986 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-10 22:33:57 +9, + RawFormat: Kouji Matsui 1636551237 0900 + }, + Message: checkout: moving from main to master + }, + { + Old: { + HashCode: cb9b168ff973ce766d55e8697b3aea2c93ad3986 + }, + Current: { + HashCode: 30aaea993cc0a3cb1dad2968d3e5f4d90a287e25 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-10 22:50:12 +9, + RawFormat: Kouji Matsui 1636552212 0900 + }, + Message: commit: Upgraded .NET 6.0. + }, + { + Old: { + HashCode: 30aaea993cc0a3cb1dad2968d3e5f4d90a287e25 + }, + Current: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Message: commit: Added installation .NET 6 SDK on GitHub Actions. + }, + { + Old: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Current: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-13 20:57:34 +2, + RawFormat: Julien Richard 1684004254 0200 + }, + Message: reset: moving to HEAD + }, + { + Old: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Current: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-13 20:58:04 +2, + RawFormat: Julien Richard 1684004284 0200 + }, + Message: reset: moving to HEAD + }, + { + Old: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Current: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-13 20:59:01 +2, + RawFormat: Julien Richard 1684004341 0200 + }, + Message: reset: moving to HEAD + }, + { + Old: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Current: { + HashCode: 1a85b097bde6e9800a1700f702202b3f232c8bda + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-14 13:39:16 +2, + RawFormat: Julien Richard 1684064356 0200 + }, + Message: pull: Fast-forward + }, + { + Old: { + HashCode: 1a85b097bde6e9800a1700f702202b3f232c8bda + }, + Current: { + HashCode: 1a85b097bde6e9800a1700f702202b3f232c8bda + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-14 13:50:18 +2, + RawFormat: Julien Richard 1684065018 0200 + }, + Message: reset: moving to HEAD + }, + { + Old: { + HashCode: 1a85b097bde6e9800a1700f702202b3f232c8bda + }, + Current: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-14 13:50:28 +2, + RawFormat: Julien Richard 1684065028 0200 + }, + Message: reset: moving to 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + { + Old: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Current: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-14 13:51:01 +2, + RawFormat: Julien Richard 1684065061 0200 + }, + Message: checkout: moving from master to master + } +] \ No newline at end of file diff --git a/GitReader.Tests/Primitive/RepositoryTests.GetRemoteBranchHeads.verified.txt b/GitReader.Tests/Primitive/RepositoryTests.GetRemoteBranchHeads.verified.txt index d946480..94a4c55 100644 --- a/GitReader.Tests/Primitive/RepositoryTests.GetRemoteBranchHeads.verified.txt +++ b/GitReader.Tests/Primitive/RepositoryTests.GetRemoteBranchHeads.verified.txt @@ -1,36 +1,49 @@ [ { Name: origin/appveyor, + RelativePath: refs/remotes/origin/appveyor, Target: { HashCode: 0a064ec9cd2199e1ecf879496b55d5e956e546ac } }, { Name: origin/devel, + RelativePath: refs/remotes/origin/devel, Target: { HashCode: f2f51b6fe6076ca630ca66c5c9f451217762652a } }, + { + Name: origin/develop, + RelativePath: refs/remotes/origin/develop, + Target: { + HashCode: d1e1a7d34cadde9a4cd3579a7f676180549677ca + } + }, { Name: origin/expression-tree, + RelativePath: refs/remotes/origin/expression-tree, Target: { HashCode: d449e3191e52be96c29ef47992a3bf78b0c759b1 } }, { Name: origin/HEAD, + RelativePath: refs/remotes/origin/HEAD, Target: { - HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + HashCode: 1a85b097bde6e9800a1700f702202b3f232c8bda } }, { Name: origin/master, + RelativePath: refs/remotes/origin/master, Target: { - HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + HashCode: 1a85b097bde6e9800a1700f702202b3f232c8bda } }, { Name: origin/netcore, + RelativePath: refs/remotes/origin/netcore, Target: { HashCode: f690f0e7bf703582a1fad7e6f1c2d1586390f43d } diff --git a/GitReader.Tests/Primitive/RepositoryTests.GetStashes.verified.txt b/GitReader.Tests/Primitive/RepositoryTests.GetStashes.verified.txt new file mode 100644 index 0000000..772096d --- /dev/null +++ b/GitReader.Tests/Primitive/RepositoryTests.GetStashes.verified.txt @@ -0,0 +1,29 @@ +[ + { + Current: { + HashCode: 8a770120d675b4e78872475cfd69c7aba6097eae + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-13 20:58:04 +2, + RawFormat: Julien Richard 1684004284 0200 + }, + Message: WIP on master: 9bb78d1 Added installation .NET 6 SDK on GitHub Actions. + }, + { + Old: { + HashCode: 8a770120d675b4e78872475cfd69c7aba6097eae + }, + Current: { + HashCode: 01513a037003eae04bae543fd21f3f06cefd991b + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-13 20:59:01 +2, + RawFormat: Julien Richard 1684004341 0200 + }, + Message: On master: Stash with custom message + } +] diff --git a/GitReader.Tests/Primitive/RepositoryTests.GetTags.verified.txt b/GitReader.Tests/Primitive/RepositoryTests.GetTags.verified.txt index 8604ec5..5bc3c2a 100644 --- a/GitReader.Tests/Primitive/RepositoryTests.GetTags.verified.txt +++ b/GitReader.Tests/Primitive/RepositoryTests.GetTags.verified.txt @@ -138,5 +138,12 @@ }, Type: Commit, Name: 2.1.0 + }, + { + Hash: { + HashCode: 63a8f2c84a8c1b2cf6eabd3e1bd7f1971b912a91 + }, + Type: Commit, + Name: 2.2.0 } ] \ No newline at end of file diff --git a/GitReader.Tests/Primitive/RepositoryTests.cs b/GitReader.Tests/Primitive/RepositoryTests.cs index d1d476a..590aca2 100644 --- a/GitReader.Tests/Primitive/RepositoryTests.cs +++ b/GitReader.Tests/Primitive/RepositoryTests.cs @@ -206,4 +206,24 @@ public async Task GetRemoteUrls() await Verifier.Verify(repository.RemoteUrls); } + + [Test] + public async Task GetStashes() + { + using var repository = await Repository.Factory.OpenPrimitiveAsync( + RepositoryTestsSetUp.BasePath); + + await Verifier.Verify(repository.GetStashesAsync()); + } + + [Test] + public async Task GetHeadRefLog() + { + using var repository = await Repository.Factory.OpenPrimitiveAsync( + RepositoryTestsSetUp.BasePath); + + var headRef = await repository.GetCurrentHeadReferenceAsync(); + + await Verifier.Verify(repository.GetRefLogAsync(headRef!.Value)); + } } diff --git a/GitReader.Tests/Structures/RepositoryTests.GetBranch.verified.txt b/GitReader.Tests/Structures/RepositoryTests.GetBranch.verified.txt index 0539057..775aa12 100644 --- a/GitReader.Tests/Structures/RepositoryTests.GetBranch.verified.txt +++ b/GitReader.Tests/Structures/RepositoryTests.GetBranch.verified.txt @@ -18,14 +18,6 @@ }, Subject: Added installation .NET 6 SDK on GitHub Actions., Body: , - Branches: [], - RemoteBranches: [ - { - Name: origin/HEAD - }, - { - Name: origin/master - } - ] + Branches: [] } } \ No newline at end of file diff --git a/GitReader.Tests/Structures/RepositoryTests.GetBranchesFromCommit.verified.txt b/GitReader.Tests/Structures/RepositoryTests.GetBranchesFromCommit.verified.txt index 427b7ce..230e485 100644 --- a/GitReader.Tests/Structures/RepositoryTests.GetBranchesFromCommit.verified.txt +++ b/GitReader.Tests/Structures/RepositoryTests.GetBranchesFromCommit.verified.txt @@ -19,15 +19,7 @@ }, Subject: Added installation .NET 6 SDK on GitHub Actions., Body: , - Branches: [], - RemoteBranches: [ - { - Name: origin/HEAD - }, - { - Name: origin/master - } - ] + Branches: [] } } ] \ No newline at end of file diff --git a/GitReader.Tests/Structures/RepositoryTests.GetCurrentHead.verified.txt b/GitReader.Tests/Structures/RepositoryTests.GetCurrentHead.verified.txt index 1815a4c..28a2406 100644 --- a/GitReader.Tests/Structures/RepositoryTests.GetCurrentHead.verified.txt +++ b/GitReader.Tests/Structures/RepositoryTests.GetCurrentHead.verified.txt @@ -22,14 +22,6 @@ { Name: master } - ], - RemoteBranches: [ - { - Name: origin/HEAD - }, - { - Name: origin/master - } ] } } \ No newline at end of file diff --git a/GitReader.Tests/Structures/RepositoryTests.GetHeadRefLog.verified.txt b/GitReader.Tests/Structures/RepositoryTests.GetHeadRefLog.verified.txt new file mode 100644 index 0000000..de65d4a --- /dev/null +++ b/GitReader.Tests/Structures/RepositoryTests.GetHeadRefLog.verified.txt @@ -0,0 +1,530 @@ +[ + { + Commit: { + Hash: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Subject: Added installation .NET 6 SDK on GitHub Actions., + Body: , + Branches: [ + { + Name: master + } + ] + }, + OldCommit: { + Hash: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Subject: Added installation .NET 6 SDK on GitHub Actions., + Body: , + Branches: [ + { + Name: master + } + ] + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-14 13:51:01 +2, + RawFormat: Julien Richard 1684065061 0200 + }, + Message: checkout: moving from master to master + }, + { + Commit: { + Hash: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Subject: Added installation .NET 6 SDK on GitHub Actions., + Body: , + Branches: [ + { + Name: master + } + ] + }, + OldCommit: { + Hash: { + HashCode: 1a85b097bde6e9800a1700f702202b3f232c8bda + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2023-04-23 20:31:48 +9, + RawFormat: Kouji Matsui 1682249508 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2023-04-23 20:31:48 +9, + RawFormat: Kouji Matsui 1682249508 0900 + }, + Subject: Updated GA script., + Body: , + RemoteBranches: [ + { + Name: origin/HEAD + }, + { + Name: origin/master + } + ] + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-14 13:50:28 +2, + RawFormat: Julien Richard 1684065028 0200 + }, + Message: reset: moving to 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + { + Commit: { + Hash: { + HashCode: 1a85b097bde6e9800a1700f702202b3f232c8bda + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2023-04-23 20:31:48 +9, + RawFormat: Kouji Matsui 1682249508 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2023-04-23 20:31:48 +9, + RawFormat: Kouji Matsui 1682249508 0900 + }, + Subject: Updated GA script., + Body: , + RemoteBranches: [ + { + Name: origin/HEAD + }, + { + Name: origin/master + } + ] + }, + OldCommit: { + Hash: { + HashCode: 1a85b097bde6e9800a1700f702202b3f232c8bda + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2023-04-23 20:31:48 +9, + RawFormat: Kouji Matsui 1682249508 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2023-04-23 20:31:48 +9, + RawFormat: Kouji Matsui 1682249508 0900 + }, + Subject: Updated GA script., + Body: , + RemoteBranches: [ + { + Name: origin/HEAD + }, + { + Name: origin/master + } + ] + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-14 13:50:18 +2, + RawFormat: Julien Richard 1684065018 0200 + }, + Message: reset: moving to HEAD + }, + { + Commit: { + Hash: { + HashCode: 1a85b097bde6e9800a1700f702202b3f232c8bda + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2023-04-23 20:31:48 +9, + RawFormat: Kouji Matsui 1682249508 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2023-04-23 20:31:48 +9, + RawFormat: Kouji Matsui 1682249508 0900 + }, + Subject: Updated GA script., + Body: , + RemoteBranches: [ + { + Name: origin/HEAD + }, + { + Name: origin/master + } + ] + }, + OldCommit: { + Hash: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Subject: Added installation .NET 6 SDK on GitHub Actions., + Body: , + Branches: [ + { + Name: master + } + ] + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-14 13:39:16 +2, + RawFormat: Julien Richard 1684064356 0200 + }, + Message: pull: Fast-forward + }, + { + Commit: { + Hash: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Subject: Added installation .NET 6 SDK on GitHub Actions., + Body: , + Branches: [ + { + Name: master + } + ] + }, + OldCommit: { + Hash: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Subject: Added installation .NET 6 SDK on GitHub Actions., + Body: , + Branches: [ + { + Name: master + } + ] + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-13 20:59:01 +2, + RawFormat: Julien Richard 1684004341 0200 + }, + Message: reset: moving to HEAD + }, + { + Commit: { + Hash: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Subject: Added installation .NET 6 SDK on GitHub Actions., + Body: , + Branches: [ + { + Name: master + } + ] + }, + OldCommit: { + Hash: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Subject: Added installation .NET 6 SDK on GitHub Actions., + Body: , + Branches: [ + { + Name: master + } + ] + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-13 20:58:04 +2, + RawFormat: Julien Richard 1684004284 0200 + }, + Message: reset: moving to HEAD + }, + { + Commit: { + Hash: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Subject: Added installation .NET 6 SDK on GitHub Actions., + Body: , + Branches: [ + { + Name: master + } + ] + }, + OldCommit: { + Hash: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Subject: Added installation .NET 6 SDK on GitHub Actions., + Body: , + Branches: [ + { + Name: master + } + ] + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-13 20:57:34 +2, + RawFormat: Julien Richard 1684004254 0200 + }, + Message: reset: moving to HEAD + }, + { + Commit: { + Hash: { + HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1 + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Subject: Added installation .NET 6 SDK on GitHub Actions., + Body: , + Branches: [ + { + Name: master + } + ] + }, + OldCommit: { + Hash: { + HashCode: 30aaea993cc0a3cb1dad2968d3e5f4d90a287e25 + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-10 22:50:12 +9, + RawFormat: Kouji Matsui 1636552212 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-10 22:50:12 +9, + RawFormat: Kouji Matsui 1636552212 0900 + }, + Subject: Upgraded .NET 6.0., + Body: , + Tags: [ + { + Hash: { + HashCode: 30aaea993cc0a3cb1dad2968d3e5f4d90a287e25 + }, + Name: 2.1.0, + Type: Commit + } + ] + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-11 09:40:12 +9, + RawFormat: Kouji Matsui 1636591212 0900 + }, + Message: commit: Added installation .NET 6 SDK on GitHub Actions. + }, + { + Commit: { + Hash: { + HashCode: 30aaea993cc0a3cb1dad2968d3e5f4d90a287e25 + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-10 22:50:12 +9, + RawFormat: Kouji Matsui 1636552212 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-10 22:50:12 +9, + RawFormat: Kouji Matsui 1636552212 0900 + }, + Subject: Upgraded .NET 6.0., + Body: , + Tags: [ + { + Hash: { + HashCode: 30aaea993cc0a3cb1dad2968d3e5f4d90a287e25 + }, + Name: 2.1.0, + Type: Commit + } + ] + }, + OldCommit: { + Hash: { + HashCode: cb9b168ff973ce766d55e8697b3aea2c93ad3986 + }, + Author: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-01-21 00:21:32 +9, + RawFormat: Kouji Matsui 1611156092 0900 + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-01-21 00:21:32 +9, + RawFormat: Kouji Matsui 1611156092 0900 + }, + Subject: Update badge., + Body: + }, + Committer: { + Name: Kouji Matsui, + MailAddress: k@kekyo.net, + Date: 2021-11-10 22:50:12 +9, + RawFormat: Kouji Matsui 1636552212 0900 + }, + Message: commit: Upgraded .NET 6.0. + } +] \ No newline at end of file diff --git a/GitReader.Tests/Structures/RepositoryTests.GetStashes.verified.txt b/GitReader.Tests/Structures/RepositoryTests.GetStashes.verified.txt new file mode 100644 index 0000000..1f1493e --- /dev/null +++ b/GitReader.Tests/Structures/RepositoryTests.GetStashes.verified.txt @@ -0,0 +1,58 @@ +[ + { + Commit: { + Hash: { + HashCode: 01513a037003eae04bae543fd21f3f06cefd991b + }, + Author: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-13 20:59:01 +2, + RawFormat: Julien Richard 1684004341 0200 + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-13 20:59:01 +2, + RawFormat: Julien Richard 1684004341 0200 + }, + Subject: On master: Stash with custom message, + Body: + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-13 20:59:01 +2, + RawFormat: Julien Richard 1684004341 0200 + }, + Message: On master: Stash with custom message + }, + { + Commit: { + Hash: { + HashCode: 8a770120d675b4e78872475cfd69c7aba6097eae + }, + Author: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-13 20:58:04 +2, + RawFormat: Julien Richard 1684004284 0200 + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-13 20:58:04 +2, + RawFormat: Julien Richard 1684004284 0200 + }, + Subject: WIP on master: 9bb78d1 Added installation .NET 6 SDK on GitHub Actions., + Body: + }, + Committer: { + Name: Julien Richard, + MailAddress: julien.richard@ubisoft.com, + Date: 2023-05-13 20:58:04 +2, + RawFormat: Julien Richard 1684004284 0200 + }, + Message: WIP on master: 9bb78d1 Added installation .NET 6 SDK on GitHub Actions. + } +] \ No newline at end of file diff --git a/GitReader.Tests/Structures/RepositoryTests.TraverseBranchCommits.verified.txt b/GitReader.Tests/Structures/RepositoryTests.TraverseBranchCommits.verified.txt index a929333..ccf9691 100644 --- a/GitReader.Tests/Structures/RepositoryTests.TraverseBranchCommits.verified.txt +++ b/GitReader.Tests/Structures/RepositoryTests.TraverseBranchCommits.verified.txt @@ -21,14 +21,6 @@ { Name: master } - ], - RemoteBranches: [ - { - Name: origin/HEAD - }, - { - Name: origin/master - } ] }, { diff --git a/GitReader.Tests/Structures/RepositoryTests.cs b/GitReader.Tests/Structures/RepositoryTests.cs index 2d867cc..39bf8aa 100644 --- a/GitReader.Tests/Structures/RepositoryTests.cs +++ b/GitReader.Tests/Structures/RepositoryTests.cs @@ -213,4 +213,21 @@ public async Task GetRemoteUrls() await Verifier.Verify(repository.RemoteUrls); } + + [Test] + public async Task GetStashes() + { + using var repository = await Repository.Factory.OpenStructureAsync(RepositoryTestsSetUp.BasePath); + + await Verifier.Verify(repository.Stashes); + } + + [Test] + public async Task GetHeadRefLog() + { + using var repository = await Repository.Factory.OpenStructureAsync(RepositoryTestsSetUp.BasePath); + + var refLog = repository.GetHeadReflogAsync(); + await Verifier.Verify(refLog); + } } diff --git a/GitReader.Tests/artifacts/test1.zip b/GitReader.Tests/artifacts/test1.zip index 7be394e..83ea645 100644 Binary files a/GitReader.Tests/artifacts/test1.zip and b/GitReader.Tests/artifacts/test1.zip differ diff --git a/GitReader/Primitive/RepositoryExtension.cs b/GitReader/Primitive/RepositoryExtension.cs index 1631f6f..79e0bfb 100644 --- a/GitReader/Primitive/RepositoryExtension.cs +++ b/GitReader/Primitive/RepositoryExtension.cs @@ -63,6 +63,17 @@ public static Task GetTagReferencesAsync( this PrimitiveRepository repository, CancellationToken ct = default) => RepositoryAccessor.ReadReferencesAsync(repository, ReferenceTypes.Tags, ct); + + public static Task GetStashesAsync( + this PrimitiveRepository repository, + CancellationToken ct = default) => + RepositoryAccessor.ReadStashesAsync(repository, ct); + + public static Task GetRefLogAsync( + this PrimitiveRepository repository, + PrimitiveReference reference, + CancellationToken ct = default) => + RepositoryAccessor.ReadRefLogAsync(repository, reference, ct); public static Task GetTreeAsync( this PrimitiveRepository repository, diff --git a/GitReader/Structures/RepositoryExtension.cs b/GitReader/Structures/RepositoryExtension.cs index f672090..09ede9e 100644 --- a/GitReader/Structures/RepositoryExtension.cs +++ b/GitReader/Structures/RepositoryExtension.cs @@ -49,6 +49,10 @@ public static Task OpenBlobAsync( public static string GetMessage( this Commit commit) => commit.message; + + public static Task GetHeadReflogAsync( + this StructuredRepository repository, CancellationToken ct = default) => + RepositoryFacade.GetHeadRefLogAsync(repository, new WeakReference(repository), ct); public static void Deconstruct( this StructuredRepository repository,