diff options
author | nulltoken <emeric.fermas@gmail.com> | 2015-07-17 09:08:03 +0300 |
---|---|---|
committer | nulltoken <emeric.fermas@gmail.com> | 2015-07-17 09:08:03 +0300 |
commit | f4a60014642ae4d050bf2db46a03b862ef7e8040 (patch) | |
tree | b573690dc0908d79476b9b4342ec50cfde177ff5 | |
parent | c7f10bb481ef0a17966662fd7cdd6da038c3b38f (diff) | |
parent | f68697b7d6a8db7f5fde86e8dc69b7b497d26156 (diff) |
Merge pull request #1132 from psawey/remotels-symref
Remote LS able to handle Symbolic References
-rw-r--r-- | LibGit2Sharp.Tests/NetworkFixture.cs | 37 | ||||
-rw-r--r-- | LibGit2Sharp.Tests/PushFixture.cs | 4 | ||||
-rw-r--r-- | LibGit2Sharp.Tests/RepositoryFixture.cs | 40 | ||||
-rw-r--r-- | LibGit2Sharp/Core/Proxy.cs | 36 | ||||
-rw-r--r-- | LibGit2Sharp/Network.cs | 10 | ||||
-rw-r--r-- | LibGit2Sharp/Repository.cs | 4 |
6 files changed, 97 insertions, 34 deletions
diff --git a/LibGit2Sharp.Tests/NetworkFixture.cs b/LibGit2Sharp.Tests/NetworkFixture.cs index d93273d1..3383234f 100644 --- a/LibGit2Sharp.Tests/NetworkFixture.cs +++ b/LibGit2Sharp.Tests/NetworkFixture.cs @@ -22,19 +22,22 @@ namespace LibGit2Sharp.Tests using (var repo = new Repository(repoPath)) { Remote remote = repo.Network.Remotes.Add(remoteName, url); - IList<DirectReference> references = repo.Network.ListReferences(remote).ToList(); + IList<Reference> references = repo.Network.ListReferences(remote).ToList(); - foreach (var directReference in references) + + foreach (var reference in references) { // None of those references point to an existing // object in this brand new repository - Assert.Null(directReference.Target); + Assert.Null(reference.ResolveToDirectReference().Target); } List<Tuple<string, string>> actualRefs = references. - Select(directRef => new Tuple<string, string>(directRef.CanonicalName, directRef.TargetIdentifier)).ToList(); + Select(directRef => new Tuple<string, string>(directRef.CanonicalName, directRef.ResolveToDirectReference() + .TargetIdentifier)).ToList(); Assert.Equal(TestRemoteRefs.ExpectedRemoteRefs.Count, actualRefs.Count); + Assert.True(references.Single(reference => reference.CanonicalName == "HEAD") is SymbolicReference); for (int i = 0; i < TestRemoteRefs.ExpectedRemoteRefs.Count; i++) { Assert.Equal(TestRemoteRefs.ExpectedRemoteRefs[i].Item2, actualRefs[i].Item2); @@ -53,19 +56,21 @@ namespace LibGit2Sharp.Tests using (var repo = new Repository(repoPath)) { - IList<DirectReference> references = repo.Network.ListReferences(url).ToList(); + IList<Reference> references = repo.Network.ListReferences(url).ToList(); - foreach (var directReference in references) + foreach (var reference in references) { // None of those references point to an existing // object in this brand new repository - Assert.Null(directReference.Target); + Assert.Null(reference.ResolveToDirectReference().Target); } List<Tuple<string, string>> actualRefs = references. - Select(directRef => new Tuple<string, string>(directRef.CanonicalName, directRef.TargetIdentifier)).ToList(); + Select(directRef => new Tuple<string, string>(directRef.CanonicalName, directRef.ResolveToDirectReference() + .TargetIdentifier)).ToList(); Assert.Equal(TestRemoteRefs.ExpectedRemoteRefs.Count, actualRefs.Count); + Assert.True(references.Single(reference => reference.CanonicalName == "HEAD") is SymbolicReference); for (int i = 0; i < TestRemoteRefs.ExpectedRemoteRefs.Count; i++) { Assert.Equal(TestRemoteRefs.ExpectedRemoteRefs[i].Item2, actualRefs[i].Item2); @@ -87,18 +92,22 @@ namespace LibGit2Sharp.Tests using (var repo = new Repository(clonedRepoPath)) { Remote remote = repo.Network.Remotes[remoteName]; - IEnumerable<DirectReference> references = repo.Network.ListReferences(remote); + IEnumerable<Reference> references = repo.Network.ListReferences(remote).ToList(); var actualRefs = new List<Tuple<string,string>>(); - foreach(DirectReference reference in references) + foreach(Reference reference in references) { Assert.NotNull(reference.CanonicalName); - Assert.NotNull(reference.Target); - actualRefs.Add(new Tuple<string, string>(reference.CanonicalName, reference.Target.Id.Sha)); + + var directReference = reference.ResolveToDirectReference(); + + Assert.NotNull(directReference.Target); + actualRefs.Add(new Tuple<string, string>(reference.CanonicalName, directReference.Target.Id.Sha)); } Assert.Equal(TestRemoteRefs.ExpectedRemoteRefs.Count, actualRefs.Count); + Assert.True(references.Single(reference => reference.CanonicalName == "HEAD") is SymbolicReference); for (int i = 0; i < TestRemoteRefs.ExpectedRemoteRefs.Count; i++) { Assert.Equal(TestRemoteRefs.ExpectedRemoteRefs[i].Item1, actualRefs[i].Item1); @@ -123,9 +132,9 @@ namespace LibGit2Sharp.Tests var references = repo.Network.ListReferences(remote, Constants.PrivateRepoCredentials); - foreach (var directReference in references) + foreach (var reference in references) { - Assert.NotNull(directReference); + Assert.NotNull(reference); } } } diff --git a/LibGit2Sharp.Tests/PushFixture.cs b/LibGit2Sharp.Tests/PushFixture.cs index c1aab1f0..7dde5efd 100644 --- a/LibGit2Sharp.Tests/PushFixture.cs +++ b/LibGit2Sharp.Tests/PushFixture.cs @@ -199,9 +199,9 @@ namespace LibGit2Sharp.Tests private static void AssertRemoteHeadTipEquals(IRepository localRepo, string sha) { var remoteReferences = localRepo.Network.ListReferences(localRepo.Network.Remotes.Single()); - DirectReference remoteHead = remoteReferences.Single(r => r.CanonicalName == "HEAD"); + Reference remoteHead = remoteReferences.Single(r => r.CanonicalName == "HEAD"); - Assert.Equal(sha, remoteHead.TargetIdentifier); + Assert.Equal(sha, remoteHead.ResolveToDirectReference().TargetIdentifier); } private void UpdateTheRemoteRepositoryWithANewCommit(string remoteRepoPath) diff --git a/LibGit2Sharp.Tests/RepositoryFixture.cs b/LibGit2Sharp.Tests/RepositoryFixture.cs index 1828e977..2453f7bf 100644 --- a/LibGit2Sharp.Tests/RepositoryFixture.cs +++ b/LibGit2Sharp.Tests/RepositoryFixture.cs @@ -679,7 +679,7 @@ namespace LibGit2Sharp.Tests InconclusiveIf(() => string.IsNullOrEmpty(Constants.PrivateRepoUrl), "Populate Constants.PrivateRepo* to run this test"); - IEnumerable<DirectReference> references = Repository.ListRemoteReferences(Constants.PrivateRepoUrl, + IEnumerable<Reference> references = Repository.ListRemoteReferences(Constants.PrivateRepoUrl, Constants.PrivateRepoCredentials); foreach (var reference in references) @@ -694,12 +694,13 @@ namespace LibGit2Sharp.Tests [InlineData("git://github.com/libgit2/TestGitRepository.git")] public void CanListRemoteReferences(string url) { - IEnumerable<DirectReference> references = Repository.ListRemoteReferences(url); + IEnumerable<Reference> references = Repository.ListRemoteReferences(url).ToList(); List<Tuple<string, string>> actualRefs = references. - Select(directRef => new Tuple<string, string>(directRef.CanonicalName, directRef.TargetIdentifier)).ToList(); + Select(reference => new Tuple<string, string>(reference.CanonicalName, reference.ResolveToDirectReference().TargetIdentifier)).ToList(); Assert.Equal(TestRemoteRefs.ExpectedRemoteRefs.Count, actualRefs.Count); + Assert.True(references.Single(reference => reference.CanonicalName == "HEAD") is SymbolicReference); for (int i = 0; i < TestRemoteRefs.ExpectedRemoteRefs.Count; i++) { Assert.Equal(TestRemoteRefs.ExpectedRemoteRefs[i].Item2, actualRefs[i].Item2); @@ -707,11 +708,35 @@ namespace LibGit2Sharp.Tests } } + [Fact] + public void CanListRemoteReferencesWithDetachedRemoteHead() + { + string originalRepoPath = SandboxStandardTestRepo(); + + string detachedHeadSha; + + using (var originalRepo = new Repository(originalRepoPath)) + { + detachedHeadSha = originalRepo.Head.Tip.Sha; + originalRepo.Checkout(detachedHeadSha); + + Assert.True(originalRepo.Info.IsHeadDetached); + } + + IEnumerable<Reference> references = Repository.ListRemoteReferences(originalRepoPath); + + Reference head = references.SingleOrDefault(reference => reference.CanonicalName == "HEAD"); + + Assert.NotNull(head); + Assert.True(head is DirectReference); + Assert.Equal(detachedHeadSha, head.TargetIdentifier); + } + [Theory] [InlineData("http://github.com/libgit2/TestGitRepository")] public void ReadingReferenceRepositoryThroughListRemoteReferencesThrows(string url) { - IEnumerable<DirectReference> references = Repository.ListRemoteReferences(url); + IEnumerable<Reference> references = Repository.ListRemoteReferences(url); foreach (var reference in references) { @@ -724,11 +749,14 @@ namespace LibGit2Sharp.Tests [InlineData("http://github.com/libgit2/TestGitRepository")] public void ReadingReferenceTargetFromListRemoteReferencesThrows(string url) { - IEnumerable<DirectReference> references = Repository.ListRemoteReferences(url); + IEnumerable<Reference> references = Repository.ListRemoteReferences(url); foreach (var reference in references) { - Assert.Throws<InvalidOperationException>(() => reference.Target); + Assert.Throws<InvalidOperationException>(() => + { + var target = reference.ResolveToDirectReference().Target; + }); } } } diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs index f442d7b7..c170cb39 100644 --- a/LibGit2Sharp/Core/Proxy.cs +++ b/LibGit2Sharp/Core/Proxy.cs @@ -2147,7 +2147,7 @@ namespace LibGit2Sharp.Core } } - public static IEnumerable<DirectReference> git_remote_ls(Repository repository, RemoteSafeHandle remote) + public static IEnumerable<Reference> git_remote_ls(Repository repository, RemoteSafeHandle remote) { IntPtr heads; UIntPtr count; @@ -2162,26 +2162,52 @@ namespace LibGit2Sharp.Core throw new OverflowException(); } - var refs = new List<DirectReference>(); + var directRefs = new Dictionary<string, Reference>(); + var symRefs = new Dictionary<string, string>(); + IntPtr currentHead = heads; for (int i = 0; i < intCount; i++) { var remoteHead = Marshal.ReadIntPtr(currentHead).MarshalAs<GitRemoteHead>(); + string name = LaxUtf8Marshaler.FromNative(remoteHead.NamePtr); + string symRefTarget = LaxUtf8Marshaler.FromNative(remoteHead.SymRefTargetPtr); + // The name pointer should never be null - if it is, // this indicates a bug somewhere (libgit2, server, etc). - if (remoteHead.NamePtr == IntPtr.Zero) + if (string.IsNullOrEmpty(name)) { throw new InvalidOperationException("Not expecting null value for reference name."); } - string name = LaxUtf8Marshaler.FromNative(remoteHead.NamePtr); - refs.Add(new DirectReference(name, repository, remoteHead.Oid)); + if (!string.IsNullOrEmpty(symRefTarget)) + { + symRefs.Add(name, symRefTarget); + } + else + { + directRefs.Add(name, new DirectReference(name, repository, remoteHead.Oid)); + } currentHead = IntPtr.Add(currentHead, IntPtr.Size); } + for (int i = 0; i < symRefs.Count; i++) + { + var symRef = symRefs.ElementAt(i); + + if (!directRefs.ContainsKey(symRef.Value)) + { + throw new InvalidOperationException("Symbolic reference target not found in direct reference results."); + } + + directRefs.Add(symRef.Key, new SymbolicReference(repository, symRef.Key, symRef.Value, directRefs[symRef.Value])); + } + + var refs = directRefs.Values.ToList(); + refs.Sort((r1, r2) => String.CompareOrdinal(r1.CanonicalName, r2.CanonicalName)); + return refs; } diff --git a/LibGit2Sharp/Network.cs b/LibGit2Sharp/Network.cs index 55f773f4..be3f2423 100644 --- a/LibGit2Sharp/Network.cs +++ b/LibGit2Sharp/Network.cs @@ -48,7 +48,7 @@ namespace LibGit2Sharp /// </summary> /// <param name="remote">The <see cref="Remote"/> to list from.</param> /// <returns>The references in the <see cref="Remote"/> repository.</returns> - public virtual IEnumerable<DirectReference> ListReferences(Remote remote) + public virtual IEnumerable<Reference> ListReferences(Remote remote) { Ensure.ArgumentNotNull(remote, "remote"); @@ -67,7 +67,7 @@ namespace LibGit2Sharp /// <param name="remote">The <see cref="Remote"/> to list from.</param> /// <param name="credentialsProvider">The <see cref="Func{Credentials}"/> used to connect to remote repository.</param> /// <returns>The references in the <see cref="Remote"/> repository.</returns> - public virtual IEnumerable<DirectReference> ListReferences(Remote remote, CredentialsHandler credentialsProvider) + public virtual IEnumerable<Reference> ListReferences(Remote remote, CredentialsHandler credentialsProvider) { Ensure.ArgumentNotNull(remote, "remote"); Ensure.ArgumentNotNull(credentialsProvider, "credentialsProvider"); @@ -86,7 +86,7 @@ namespace LibGit2Sharp /// </summary> /// <param name="url">The url to list from.</param> /// <returns>The references in the remote repository.</returns> - public virtual IEnumerable<DirectReference> ListReferences(string url) + public virtual IEnumerable<Reference> ListReferences(string url) { Ensure.ArgumentNotNull(url, "url"); @@ -105,7 +105,7 @@ namespace LibGit2Sharp /// <param name="url">The url to list from.</param> /// <param name="credentialsProvider">The <see cref="Func{Credentials}"/> used to connect to remote repository.</param> /// <returns>The references in the remote repository.</returns> - public virtual IEnumerable<DirectReference> ListReferences(string url, CredentialsHandler credentialsProvider) + public virtual IEnumerable<Reference> ListReferences(string url, CredentialsHandler credentialsProvider) { Ensure.ArgumentNotNull(url, "url"); Ensure.ArgumentNotNull(credentialsProvider, "credentialsProvider"); @@ -113,7 +113,7 @@ namespace LibGit2Sharp return ListReferencesInternal(url, credentialsProvider); } - private IEnumerable<DirectReference> ListReferencesInternal(string url, CredentialsHandler credentialsProvider) + private IEnumerable<Reference> ListReferencesInternal(string url, CredentialsHandler credentialsProvider) { using (RemoteSafeHandle remoteHandle = BuildRemoteSafeHandle(repository.Handle, url)) { diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index a3303d99..730da7ea 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -563,7 +563,7 @@ namespace LibGit2Sharp /// </para> /// <param name="url">The url to list from.</param> /// <returns>The references in the remote repository.</returns> - public static IEnumerable<DirectReference> ListRemoteReferences(string url) + public static IEnumerable<Reference> ListRemoteReferences(string url) { return ListRemoteReferences(url, null); } @@ -579,7 +579,7 @@ namespace LibGit2Sharp /// <param name="url">The url to list from.</param> /// <param name="credentialsProvider">The <see cref="Func{Credentials}"/> used to connect to remote repository.</param> /// <returns>The references in the remote repository.</returns> - public static IEnumerable<DirectReference> ListRemoteReferences(string url, CredentialsHandler credentialsProvider) + public static IEnumerable<Reference> ListRemoteReferences(string url, CredentialsHandler credentialsProvider) { Ensure.ArgumentNotNull(url, "url"); |