Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GetStashes / GetRefLog #2

Merged
merged 8 commits into from
May 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ dlldata.c

# DNX
project.lock.json
artifacts/

*_i.c
*_p.c
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[
{
Name: master,
RelativePath: refs/heads/master,
Target: {
HashCode: 9bb78d13405cab568d3e213130f31beda1ce21d1
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,5 +138,12 @@
},
Type: Commit,
Name: 2.1.0
},
{
Hash: {
HashCode: 63a8f2c84a8c1b2cf6eabd3e1bd7f1971b912a91
},
Type: Commit,
Name: 2.2.0
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,6 @@
},
Subject: Added installation .NET 6 SDK on GitHub Actions.,
Body: ,
Branches: [],
RemoteBranches: [
{
Name: origin/HEAD
},
{
Name: origin/master
}
]
Branches: []
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,7 @@
},
Subject: Added installation .NET 6 SDK on GitHub Actions.,
Body: ,
Branches: [],
RemoteBranches: [
{
Name: origin/HEAD
},
{
Name: origin/master
}
]
Branches: []
}
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,6 @@
{
Name: master
}
],
RemoteBranches: [
{
Name: origin/HEAD
},
{
Name: origin/master
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,6 @@
{
Name: master
}
],
RemoteBranches: [
{
Name: origin/HEAD
},
{
Name: origin/master
}
]
},
{
Expand Down
7 changes: 7 additions & 0 deletions GitReader.Core/GitReader.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Nullable" Version="1.3.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<None Include="../Images/GitReader.100.png" Pack="true" PackagePath="" />
</ItemGroup>
Expand Down
89 changes: 75 additions & 14 deletions GitReader.Core/Internal/RepositoryAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,30 @@ internal enum ReferenceTypes

internal readonly struct ReferenceCache
{
public readonly ReadOnlyDictionary<string, Hash> Branches;
public readonly ReadOnlyDictionary<string, Hash> RemoteBranches;
public readonly ReadOnlyDictionary<string, Hash> Tags;

public ReferenceCache(
ReadOnlyDictionary<string, Hash> branches,
ReadOnlyDictionary<string, Hash> remoteBranches,
ReadOnlyDictionary<string, Hash> 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;
Expand All @@ -54,7 +62,7 @@ public ReferenceCache Combine(ReferenceCache rhs)
tags[entry.Key] = entry.Value;
}

return new(remoteBranches, tags);
return new(branches, remoteBranches, tags);
}
}

Expand Down Expand Up @@ -162,13 +170,13 @@ public static async Task<ReferenceCache> 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<string, Hash>();
var remoteBranches = new Dictionary<string, Hash>();
var tags = new Dictionary<string, Hash>();

while (true)
Expand Down Expand Up @@ -223,7 +231,7 @@ public static async Task<ReferenceCache> ReadFetchHeadsAsync(
var urlString = descriptorString.Split(' ').Last();
if (remoteNameByUrl.TryGetValue(urlString, out var remoteName))
{
branches[$"{remoteName}/{name}"] = hash;
remoteBranches[$"{remoteName}/{name}"] = hash;
}
}
else
Expand All @@ -235,7 +243,7 @@ public static async Task<ReferenceCache> ReadFetchHeadsAsync(
{
if (typeString == "branch")
{
branches[descriptorString] = hash;
remoteBranches[descriptorString] = hash;
}
else
{
Expand All @@ -244,7 +252,7 @@ public static async Task<ReferenceCache> ReadFetchHeadsAsync(
}
}

return new(branches, tags);
return new(new(new()), remoteBranches, tags);
}

public static async Task<ReferenceCache> ReadPackedRefsAsync(
Expand All @@ -254,13 +262,14 @@ public static async Task<ReferenceCache> 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<string, Hash>();
var remoteBranches = new Dictionary<string, Hash>();
var tags = new Dictionary<string, Hash>();

var separators = new[] { ' ' };
Expand Down Expand Up @@ -297,17 +306,22 @@ public static async Task<ReferenceCache> 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);
}

//////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -370,6 +384,41 @@ public static async Task<ReferenceCache> ReadPackedRefsAsync(
}
}

public static Task<PrimitiveRefLogEntry[]> ReadStashesAsync(Repository repository, CancellationToken ct)
=> ReadRefLogAsync(repository, "refs/stash", ct);

public static Task<PrimitiveRefLogEntry[]> ReadRefLogAsync(Repository repository, PrimitiveReference reference, CancellationToken ct)
=> ReadRefLogAsync(repository, reference.RelativePath, ct);

public static async Task<PrimitiveRefLogEntry[]> 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<PrimitiveRefLogEntry>();
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<PrimitiveReference[]> ReadReferencesAsync(
Repository repository,
ReferenceTypes type,
Expand All @@ -392,24 +441,36 @@ public static async Task<PrimitiveReference[]> ReadReferencesAsync(
{
return new(
path.Substring(headsPath.Length + 1).Replace(Path.DirectorySeparatorChar, '/'),
path.Substring(repository.GitPath.Length + 1).Replace(Path.DirectorySeparatorChar, '/'),
results.Hash);
}
}))).
CollectValue(reference => reference).
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)
{
if (!references.ContainsKey(entry.Key))
{
references.Add(
entry.Key,
new(entry.Key, entry.Value));
new(entry.Key,$"refs/remotes/{entry.Key}", entry.Value));
}
}
break;
Expand All @@ -420,7 +481,7 @@ public static async Task<PrimitiveReference[]> ReadReferencesAsync(
{
references.Add(
entry.Key,
new(entry.Key, entry.Value));
new(entry.Key, $"refs/tags/{entry.Key}", entry.Value));
}
}
break;
Expand Down
Loading