10000 Merge pull request #1132 from psawey/remotels-symref · github/libgit2sharp@f4a6001 · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Feb 3, 2023. It is now read-only.

Commit f4a6001

Browse files
committed
Merge pull request libgit2#1132 from psawey/remotels-symref
Remote LS able to handle Symbolic References
2 parents c7f10bb + f68697b commit f4a6001

File tree

6 files changed

+97
-34
lines changed

6 files changed

+97
-34
lines changed

LibGit2Sharp.Tests/NetworkFixture.cs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,22 @@ public void CanListRemoteReferences(string url)
2222
using (var repo = new Repository(repoPath))
2323
{
2424
Remote remote = repo.Network.Remotes.Add(remoteName, url);
25-
IList<DirectReference> references = repo.Network.ListReferences(remote).ToList();
25+
IList<Reference> references = repo.Network.ListReferences(remote).ToList();
2626

27-
foreach (var directReference in references)
27+
28+
foreach (var reference in references)
2829
{
2930
// None of those references point to an existing
3031
// object in this brand new repository
31-
Assert.Null(directReference.Target);
32+
Assert.Null(reference.ResolveToDirectReference().Target);
3233
}
3334

3435
List<Tuple<string, string>> actualRefs = references.
35-
Select(directRef => new Tuple<string, string>(directRef.CanonicalName, directRef.TargetIdentifier)).ToList();
36+
Select(directRef => new Tuple<string, string>(directRef.CanonicalName, directRef.ResolveToDirectReference()
37+
.TargetIdentifier)).ToList();
3638

3739
Assert.Equal(TestRemoteRefs.ExpectedRemoteRefs.Count, actualRefs.Count);
40+
Assert.True(references.Single(reference => reference.CanonicalName == "HEAD") is SymbolicReference);
3841
for (int i = 0; i < TestRemoteRefs.ExpectedRemoteRefs.Count; i++)
3942
{
4043
Assert.Equal(TestRemoteRefs.ExpectedRemoteRefs[i].Item2, actualRefs[i].Item2);
@@ -53,19 +56,21 @@ public void CanListRemoteReferencesFromUrl(string url)
5356

5457
using (var repo = new Repository(repoPath))
5558
{
56-
IList<DirectReference> references = repo.Network.ListReferences(url).ToList();
59+
IList<Reference> references = repo.Network.ListReferences(url).ToList();
5760

58-
foreach (var directReference in references)
61+
foreach (var reference in references)
5962
{
6063
// None of those references point to an existing
6164
// object in this brand new repository
62-
Assert.Null(directReference.Target);
65+
Assert.Null(reference.ResolveToDirectReference().Target);
6366
}
6467

6568
List<Tuple<string, string>> actualRefs = references.
66-
Select(directRef => new Tuple<string, string>(directRef.CanonicalName, directRef.TargetIdentifier)).ToList();
69+
Select(directRef => new Tuple<string, string>(directRef.CanonicalName, directRef.ResolveToDirectReference()
70+
.TargetIdentifier)).ToList();
6771

6872
Assert.Equal(TestRemoteRefs.ExpectedRemoteRefs.Count, actualRefs.Count);
73+
Assert.True(references.Single(reference => reference.CanonicalName == "HEAD") is SymbolicReference);
6974
for (int i = 0; i < TestRemoteRefs.ExpectedRemoteRefs.Count; i++)
7075
{
7176
Assert.Equal(TestRemoteRefs.ExpectedRemoteRefs[i].Item2, actualRefs[i].Item2);
@@ -87,18 +92,22 @@ public void CanListRemoteReferenceObjects()
8792
using (var repo = new Repository(clonedRepoPath))
8893
{
8994
Remote remote = repo.Network.Remotes[remoteName];
90-
IEnumerable<DirectReference> references = repo.Network.ListReferences(remote);
95+
IEnumerable<Reference> references = repo.Network.ListReferences(remote).ToList();
9196

9297
var actualRefs = new List<Tuple<string,string>>();
9398

94-
foreach(DirectReference reference in references)
99+
foreach(Reference reference in references)
95100
{
96101
Assert.NotNull(reference.CanonicalName);
97-
Assert.NotNull(reference.Target);
98-
actualRefs.Add(new Tuple<string, string>(reference.CanonicalName, reference.Target.Id.Sha));
102+
103+
var directReference = reference.ResolveToDirectReference();
104+
105+
Assert.NotNull(directReference.Target);
106+
actualRefs.Add(new Tuple<string, string>(reference.CanonicalName, directReference.Target.Id.Sha));
99107
}
100108

101109
Assert.Equal(TestRemoteRefs.ExpectedRemoteRefs.Count, actualRefs.Count);
110+
Assert.True(references.Single(reference => reference.CanonicalName == "HEAD") is SymbolicReference);
102111
for (int i = 0; i < TestRemoteRefs.ExpectedRemoteRefs.Count; i++)
103112
{
104113
Assert.Equal(TestRemoteRefs.ExpectedRemoteRefs[i].Item1, actualRefs[i].Item1);
@@ -123,9 +132,9 @@ public void CanListRemoteReferencesWithCredentials()
123132

124133
var references = repo.Network.ListReferences(remote, Constants.PrivateRepoCredentials);
125134

126-
foreach (var directReference in references)
135+
foreach (var reference in references)
127136
{
128-
Assert.NotNull(directReference);
137+
Assert.NotNull(reference);
129138
}
130139
}
131140
}

LibGit2Sharp.Tests/PushFixture.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,9 @@ public void CanForcePush()
199199
private static void AssertRemoteHeadTipEquals(IRepository localRepo, string sha)
200200
{
201201
var remoteReferences = localRepo.Network.ListReferences(localRepo.Network.Remotes.Single());
202-
DirectReference remoteHead = remoteReferences.Single(r => r.CanonicalName == "HEAD");
202+
Reference remoteHead = remoteReferences.Single(r => r.CanonicalName == "HEAD");
203203

204-
Assert.Equal(sha, remoteHead.TargetIdentifier);
204+
Assert.Equal(sha, remoteHead.ResolveToDirectReference().TargetIdentifier);
205205
}
206206

207207
private void UpdateTheRemoteRepositoryWithANewCommit(string remoteRepoPath)

LibGit2Sharp.Tests/RepositoryFixture.cs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ public void CanListRemoteReferencesWithCredentials()
679679
InconclusiveIf(() => string.IsNullOrEmpty(Constants.PrivateRepoUrl),
680680
"Populate Constants.PrivateRepo* to run this test");
681681

682-
IEnumerable<DirectReference> references = Repository.ListRemoteReferences(Constants.PrivateRepoUrl,
682+
IEnumerable<Reference> references = Repository.ListRemoteReferences(Constants.PrivateRepoUrl,
683683
Constants.PrivateRepoCredentials);
684684

685685
foreach (var reference in references)
@@ -694,24 +694,49 @@ public void CanListRemoteReferencesWithCredentials()
694694
[InlineData("git://github.com/libgit2/TestGitRepository.git")]
695695
public void CanListRemoteReferences(string url)
696696
{
697-
IEnumerable<DirectReference> references = Repository.ListRemoteReferences(url);
697+
IEnumerable<Reference> references = Repository.ListRemoteReferences(url).ToList();
698698

699699
List<Tuple<string, string>> actualRefs = references.
700-
Select(directRef => new Tuple<string, string>(directRef.CanonicalName, directRef.TargetIdentifier)).ToList();
700+
Select(reference => new Tuple<string, string>(reference.CanonicalName, reference.ResolveToDirectReference().TargetIdentifier)).ToList();
701701

702702
Assert.Equal(TestRemoteRefs.ExpectedRemoteRefs.Count, actualRefs.Count);
703+
Assert.True(references.Single(reference => reference.CanonicalName == "HEAD") is SymbolicReference);
703704
for (int i = 0; i < TestRemoteRefs.ExpectedRemoteRefs.Count; i++)
704705
{
705706
Assert.Equal(TestRemoteRefs.ExpectedRemoteRefs[i].Item2, actualRefs[i].Item2);
706707
Assert.Equal(TestRemoteRefs.ExpectedRemoteRefs[i].Item1, actualRefs[i].Item1);
707708
}
708709
}
709710

711+
[Fact]
712+
public void CanListRemoteReferencesWithDetachedRemoteHead()
713+
{
714+
string originalRepoPath = SandboxStandardTestRepo();
715+
716+
string detachedHeadSha;
717+
718+
using (var originalRepo = new Repository(originalRepoPath))
719+
{
720+
detachedHeadSha = originalRepo.Head.Tip.Sha;
721+
originalRepo.Checkout(detachedHeadSha);
722+
723+
Assert.True(originalRepo.Info.IsHeadDetached);
724+
}
725+
726+
IEnumerable<Reference> references = Repository.ListRemoteReferences(originalRepoPath);
727+
728+
Reference head = references.SingleOrDefault(reference => reference.CanonicalName == "HEAD");
729+
730+
Assert.NotNull(head);
731+
Assert.True(head is DirectReference);
732+
Assert.Equal(detachedHeadSha, head.TargetIdentifier);
733+
}
734+
710735
[Theory]
711736
[InlineData("http://github.com/libgit2/TestGitRepository")]
712737
public void ReadingReferenceRepositoryThroughListRemoteReferencesThrows(string url)
713738
{
714-
IEnumerable<DirectReference> references = Repository.ListRemoteReferences(url);
739+
IEnumerable<Reference> references = Repository.ListRemoteReferences(url);
715740

716741
foreach (var reference in references)
717742
{
@@ -724,11 +749,14 @@ public void ReadingReferenceRepositoryThroughListRemoteReferencesThrows(string u
724749
[InlineData("http://github.com/libgit2/TestGitRepository")]
725750
public void ReadingReferenceTargetFromListRemoteReferencesThrows(string url)
726751
{
727-
IEnumerable<DirectReference> references = Repository.ListRemoteReferences(url);
752+
IEnumerable<Reference> references = Repository.ListRemoteReferences(url);
728753

729754
foreach (var reference in references)
730755
{
731-
Assert.Throws<InvalidOperationException>(() => reference.Target);
756+
Assert.Throws<InvalidOperationException>(() =>
757+
{
758+
var target = reference.ResolveToDirectReference().Target;
759+
});
732760
}
733761
}
734762
}

LibGit2Sharp/Core/Proxy.cs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2147,7 +2147,7 @@ public static IList<string> git_remote_list(RepositorySafeHandle repo)
21472147
}
21482148
}
21492149

2150-
public static IEnumerable<DirectReference> git_remote_ls(Repository repository, RemoteSafeHandle remote)
2150+
public static IEnumerable<Reference> git_remote_ls(Repository repository, RemoteSafeHandle remote)
21512151
{
21522152
IntPtr heads;
21532153
UIntPtr count;
@@ -2162,26 +2162,52 @@ public static IEnumerable<DirectReference> git_remote_ls(Repository repository,
21622162
throw new OverflowException();
21632163
}
21642164

2165-
var refs = new List<DirectReference>();
2165+
var directRefs = new Dictionary<string, Reference>();
2166+
var symRefs = new Dictionary<string, string>();
2167+
21662168
IntPtr currentHead = heads;
21672169

21682170
for (int i = 0; i < intCount; i++)
21692171
{
21702172
var remoteHead = Marshal.ReadIntPtr(currentHead).MarshalAs<GitRemoteHead>();
21712173

2174+
string name = LaxUtf8Marshaler.FromNative(remoteHead.NamePtr);
2175+
string symRefTarget = LaxUtf8Marshaler.FromNative(remoteHead.SymRefTargetPtr);
2176+
21722177
// The name pointer should never be null - if it is,
21732178
// this indicates a bug somewhere (libgit2, server, etc).
2174-
if (remoteHead.NamePtr == IntPtr.Zero)
2179+
if (string.IsNullOrEmpty(name))
21752180
{
21762181
throw new InvalidOperationException("Not expecting null value for reference name.");
21772182
}
21782183

2179-
string name = LaxUtf8Marshaler.FromNative(remoteHead.NamePtr);
2180-
refs.Add(new DirectReference(name, repository, remoteHead.Oid));
2184+
if (!string.IsNullOrEmpty(symRefTarget))
2185+
{
2186+
symRefs.Add(name, symRefTarget);
2187+
}
2188+
else
2189+
{
2190+
directRefs.Add(name, new DirectReference(name, repository, remoteHead.Oid));
2191+
}
21812192

21822193
currentHead = IntPtr.Add(currentHead, IntPtr.Size);
21832194
}
21842195

2196+
for (int i = 0; i < symRefs.Count; i++)
2197+
{
2198+
var symRef = symRefs.ElementAt(i);
2199+
2200+
if (!directRefs.ContainsKey(symRef.Value))
2201+
{
2202+
throw new InvalidOperationException("Symbolic reference target not found in direct reference results.");
2203+
}
2204+
2205+
directRefs.Add(symRef.Key, new SymbolicReference(repository, symRef.Key, symRef.Value, directRefs[symRef.Value]));
2206+
}
2207+
2208+
var refs = directRefs.Values.ToList();
2209+
refs.Sort((r1, r2) => String.CompareOrdinal(r1.CanonicalName, r2.CanonicalName));
2210+
21852211
return refs;
21862212
}
21872213

LibGit2Sharp/Network.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public virtual RemoteCollection Remotes
4848
/// </summary>
4949
/// <param name="remote">The <see cref="Remote"/> to list from.</param>
5050
/// <returns>The references in the <see cref="Remote"/> repository.</returns>
51-
public virtual IEnumerable<DirectReference> ListReferences(Remote remote)
51+
public virtual IEnumerable<Reference> ListReferences(Remote remote)
5252
{
5353
Ensure.ArgumentNotNull(remote, "remote");
5454

@@ -67,7 +67,7 @@ public virtual IEnumerable<DirectReference> ListReferences(Remote remote)
6767
/// <param name="remote">The <see cref="Remote"/> to list from.</param>
6868
/// <param name="credentialsProvider">The <see cref="Func{Credentials}"/> used to connect to remote repository.</param>
6969
/// <returns>The references in the <see cref="Remote"/> repository.</returns>
70-
public virtual IEnumerable<DirectReference> ListReferences(Remote remote, CredentialsHandler credentialsProvider)
70+
public virtual IEnumerable<Reference> ListReferences(Remote remote, CredentialsHandler credentialsProvider)
7171
{
7272
Ensure.ArgumentNotNull(remote, "remote");
7373
Ensure.ArgumentNotNull(credentialsProvider, "credentialsProvider");
@@ -86,7 +86,7 @@ public virtual IEnumerable<DirectReference> ListReferences(Remote remote, Creden
8686
/// </summary>
8787
/// <param name="url">The url to list from.</param>
8888
/// <returns>The references in the remote repository.</returns>
89-
public virtual IEnumerable<DirectReference> ListReferences(string url)
89+
public virtual IEnumerable<Reference> ListReferences(string url)
9090
{
9191
Ensure.ArgumentNotNull(url, "url");
9292

@@ -105,15 +105,15 @@ public virtual IEnumerable<DirectReference> ListReferences(string url)
105105
/// <param name="url">The url to list from.</param>
106106
/// <param name="credentialsProvider">The <see cref="Func{Credentials}"/> used to connect to remote repository.</param>
107107
/// <returns>The references in the remote repository.</returns>
108-
public virtual IEnumerable<DirectReference> ListReferences(string url, CredentialsHandler credentialsProvider)
108+
public virtual IEnumerable<Reference> ListReferences(string url, CredentialsHandler credentialsProvider)
109109
{
110110
Ensure.ArgumentNotNull(url, "url");
111111
Ensure.ArgumentNotNull(credentialsProvider, "credentialsProvider");
112112

113113
return ListReferencesInternal(url, credentialsProvider);
114114
}
115115

116-
private IEnumerable<DirectReference> ListReferencesInternal(string url, CredentialsHandler credentialsProvider)
116+
private IEnumerable<Reference> ListReferencesInternal(string url, CredentialsHandler credentialsProvider)
117117
{
118118
using (RemoteSafeHandle remoteHandle = BuildRemoteSafeHandle(repository.Handle, url))
119119
{

LibGit2Sharp/Repository.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ internal Commit LookupCommit(string committish)
563563
/// </para>
564564
/// <param name="url">The url to list from.</param>
565565
/// <returns>The references in the remote repository.</returns>
566-
public static IEnumerable<DirectReference> ListRemoteReferences(string url)
566+
public static IEnumerable<Reference> ListRemoteReferences(string url)
567567
{
568568
return ListRemoteReferences(url, null);
569569
}
@@ -579,7 +579,7 @@ public static IEnumerable<DirectReference> ListRemoteReferences(string url)
579579
/// <param name="url">The url to list from.</param>
580580
/// <param name="credentialsProvider">The <see cref="Func{Credentials}"/> used to connect to remote repository.</param>
581581
/// <returns>The references in the remote repository.</returns>
582-
public static IEnumerable<DirectReference> ListRemoteReferences(string url, CredentialsHandler credentialsProvider)
582+
public static IEnumerable<Reference> ListRemoteReferences(string url, CredentialsHandler credentialsProvider)
583583
{
584584
Ensure.ArgumentNotNull(url, "url");
585585

0 commit comments

Comments
 (0)
0