Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2sharp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@microsoft.com>2013-01-29 21:56:36 +0400
committernulltoken <emeric.fermas@gmail.com>2013-01-31 23:19:48 +0400
commitd255379ad3f96fc37dc4643ea72a2901b98ac328 (patch)
tree4ae975e669e1166c9f2e8f92fd001e2765b5c084
parentf4cc029b29c12eb79359e8ae7cc78900b64ba2ae (diff)
Introduce repo.Network.FetchHeads
-rw-r--r--LibGit2Sharp.Tests/FetchHeadFixture.cs126
-rw-r--r--LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj1
-rw-r--r--LibGit2Sharp/Core/NativeMethods.cs13
-rw-r--r--LibGit2Sharp/Core/Proxy.cs39
-rw-r--r--LibGit2Sharp/FetchHead.cs59
-rw-r--r--LibGit2Sharp/LibGit2Sharp.csproj2
-rw-r--r--LibGit2Sharp/Network.cs39
-rw-r--r--LibGit2Sharp/Repository.cs13
8 files changed, 292 insertions, 0 deletions
diff --git a/LibGit2Sharp.Tests/FetchHeadFixture.cs b/LibGit2Sharp.Tests/FetchHeadFixture.cs
new file mode 100644
index 00000000..059a0e75
--- /dev/null
+++ b/LibGit2Sharp.Tests/FetchHeadFixture.cs
@@ -0,0 +1,126 @@
+using LibGit2Sharp.Tests.TestHelpers;
+using System;
+using System.IO;
+using System.Linq;
+using Xunit;
+using Xunit.Extensions;
+
+namespace LibGit2Sharp.Tests
+{
+ public class FetchHeadFixture : BaseFixture
+ {
+ [Fact]
+ public void FetchHeadIsEmptyByDefault()
+ {
+ var scd = BuildSelfCleaningDirectory();
+ using (var repo = Repository.Init(scd.RootedDirectoryPath))
+ {
+ Assert.Equal(0, repo.Network.FetchHeads.Count());
+ }
+ }
+
+ private class FetchHeadExpected
+ {
+ public String Name { get; set; }
+ public String RemoteName { get; set; }
+ public String Url { get; set; }
+ public string TargetSha { get; set; }
+ public bool ForMerge { get; set; }
+ }
+
+ [Theory]
+ [InlineData("git://github.com/libgit2/TestGitRepository.git")]
+ public void CanIterateFetchHead(string url)
+ {
+ var scd = BuildSelfCleaningDirectory();
+ using (var repo = Repository.Clone(url, scd.RootedDirectoryPath))
+ {
+ repo.Reset(ResetOptions.Hard, "HEAD~2");
+
+ // Create a file, stage it, and commit it.
+ String filename = "b.txt";
+ String fullPath = Path.Combine(repo.Info.WorkingDirectory, filename);
+ File.WriteAllText(fullPath, "");
+ repo.Index.Stage(filename);
+ repo.Commit("comment", Constants.Signature, Constants.Signature);
+
+ // Issue the fetch.
+ repo.Fetch("origin");
+
+ // Retrieve the fetch heads and verify the expected result.
+ var expected = new[] {
+ new FetchHeadExpected
+ {
+ Name = "FETCH_HEAD[0]",
+ RemoteName = "refs/heads/master",
+ Url = "git://github.com/libgit2/TestGitRepository.git",
+ TargetSha = "49322bb17d3acc9146f98c97d078513228bbf3c0",
+ ForMerge = true,
+ },
+ new FetchHeadExpected
+ {
+ Name = "FETCH_HEAD[1]",
+ RemoteName = "refs/heads/first-merge",
+ Url = "git://github.com/libgit2/TestGitRepository.git",
+ TargetSha = "0966a434eb1a025db6b71485ab63a3bfbea520b6",
+ ForMerge = false,
+ },
+ new FetchHeadExpected
+ {
+ Name = "FETCH_HEAD[2]",
+ RemoteName = "refs/heads/no-parent",
+ Url = "git://github.com/libgit2/TestGitRepository.git",
+ TargetSha = "42e4e7c5e507e113ebbb7801b16b52cf867b7ce1",
+ ForMerge = false,
+ },
+ new FetchHeadExpected
+ {
+ Name = "FETCH_HEAD[3]",
+ RemoteName = "refs/tags/annotated_tag",
+ Url = "git://github.com/libgit2/TestGitRepository.git",
+ TargetSha = "d96c4e80345534eccee5ac7b07fc7603b56124cb",
+ ForMerge = false,
+ },
+ new FetchHeadExpected
+ {
+ Name = "FETCH_HEAD[4]",
+ RemoteName = "refs/tags/blob",
+ Url = "git://github.com/libgit2/TestGitRepository.git",
+ TargetSha = "55a1a760df4b86a02094a904dfa511deb5655905",
+ ForMerge = false,
+ },
+ new FetchHeadExpected
+ {
+ Name = "FETCH_HEAD[5]",
+ RemoteName = "refs/tags/commit_tree",
+ Url = "git://github.com/libgit2/TestGitRepository.git",
+ TargetSha = "8f50ba15d49353813cc6e20298002c0d17b0a9ee",
+ ForMerge = false,
+ },
+ };
+
+ VerifyFetchHead(repo.Network.FetchHeads.ToArray(), expected);
+ }
+ }
+
+ private static void VerifyFetchHead(FetchHead[] actual, FetchHeadExpected[] expected)
+ {
+ Assert.NotNull(actual);
+ Assert.NotNull(expected);
+
+ Assert.Equal(actual.Count(), expected.Count());
+
+ int i = 0;
+ foreach (FetchHead fetchHead in actual)
+ {
+ Assert.Equal(fetchHead.CanonicalName, expected[i].Name);
+ Assert.Equal(fetchHead.RemoteCanonicalName, expected[i].RemoteName);
+ Assert.Equal(fetchHead.Url, expected[i].Url);
+ Assert.Equal(fetchHead.Target.Sha, expected[i].TargetSha);
+ Assert.Equal(fetchHead.ForMerge, expected[i].ForMerge);
+
+ i++;
+ }
+ }
+ }
+}
diff --git a/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj b/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj
index feb184c3..770c38d6 100644
--- a/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj
+++ b/LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj
@@ -60,6 +60,7 @@
<Compile Include="CheckoutFixture.cs" />
<Compile Include="CloneFixture.cs" />
<Compile Include="IgnoreFixture.cs" />
+ <Compile Include="FetchHeadFixture.cs" />
<Compile Include="MergeFixture.cs" />
<Compile Include="CleanFixture.cs" />
<Compile Include="CurrentOperationFixture.cs" />
diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs
index 22a08581..21bcff21 100644
--- a/LibGit2Sharp/Core/NativeMethods.cs
+++ b/LibGit2Sharp/Core/NativeMethods.cs
@@ -720,6 +720,19 @@ namespace LibGit2Sharp.Core
[MarshalAs(UnmanagedType.Bool)] bool across_fs,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(FilePathMarshaler))] FilePath ceiling_dirs);
+ internal delegate int git_repository_fetchhead_foreach_cb(
+ IntPtr remote_name,
+ IntPtr remote_url,
+ ref GitOid oid,
+ [MarshalAs(UnmanagedType.Bool)] bool is_merge,
+ IntPtr payload);
+
+ [DllImport(libgit2)]
+ internal static extern int git_repository_fetchhead_foreach(
+ RepositorySafeHandle repo,
+ git_repository_fetchhead_foreach_cb cb,
+ IntPtr payload);
+
[DllImport(libgit2)]
internal static extern void git_repository_free(IntPtr repo);
diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs
index cb45a1b1..defc3e48 100644
--- a/LibGit2Sharp/Core/Proxy.cs
+++ b/LibGit2Sharp/Core/Proxy.cs
@@ -1346,6 +1346,19 @@ namespace LibGit2Sharp.Core
return RepositoryStateChecker(repo, NativeMethods.git_repository_head_detached);
}
+ public static ICollection<TResult> git_repository_fetchhead_foreach<TResult>(
+ RepositorySafeHandle repo,
+ Func<string, string, GitOid, bool, TResult> resultSelector)
+ {
+ return git_foreach(
+ resultSelector,
+ c => NativeMethods.git_repository_fetchhead_foreach(
+ repo,
+ (IntPtr w, IntPtr x, ref GitOid y, bool z, IntPtr p)
+ => c(Utf8Marshaler.FromNative(w), Utf8Marshaler.FromNative(x), y, z, p), IntPtr.Zero),
+ GitErrorCode.NotFound);
+ }
+
public static void git_repository_free(IntPtr repo)
{
NativeMethods.git_repository_free(repo);
@@ -1882,6 +1895,32 @@ namespace LibGit2Sharp.Core
}
}
+ public delegate TResult Func<T1, T2, T3, T4, T5, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
+
+ private static ICollection<TResult> git_foreach<T1, T2, T3, T4, TResult>(
+ Func<T1, T2, T3, T4, TResult> resultSelector,
+ Func<Func<T1, T2, T3, T4, IntPtr, int>, int> iterator,
+ params GitErrorCode[] ignoredErrorCodes)
+ {
+ using (ThreadAffinity())
+ {
+ var result = new List<TResult>();
+ var res = iterator((w, x, y, z, payload) =>
+ {
+ result.Add(resultSelector(w, x, y, z));
+ return 0;
+ });
+
+ if (ignoredErrorCodes != null && ignoredErrorCodes.Contains((GitErrorCode)res))
+ {
+ return new TResult[0];
+ }
+
+ Ensure.Success(res);
+ return result;
+ }
+ }
+
private static unsafe class Libgit2UnsafeHelper
{
public static IList<string> BuildListOf(UnSafeNativeMethods.git_strarray strArray)
diff --git a/LibGit2Sharp/FetchHead.cs b/LibGit2Sharp/FetchHead.cs
new file mode 100644
index 00000000..09f39f9f
--- /dev/null
+++ b/LibGit2Sharp/FetchHead.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Globalization;
+
+namespace LibGit2Sharp
+{
+ /// <summary>
+ /// Represents a local reference data from a remote repository which
+ /// has been retreived through a Fetch process.
+ /// </summary>
+ public class FetchHead : ReferenceWrapper<GitObject>
+ {
+ /// <summary>
+ /// Needed for mocking purposes.
+ /// </summary>
+ protected FetchHead()
+ { }
+
+ internal FetchHead(Repository repo, string remoteCanonicalName,
+ string url, ObjectId targetId, bool forMerge, int index)
+ : base(repo, new DirectReference(
+ string.Format(CultureInfo.InvariantCulture, "FETCH_HEAD[{0}]", index),
+ repo, targetId), r => r.CanonicalName)
+ {
+ Url = url;
+ ForMerge = forMerge;
+ RemoteCanonicalName = remoteCanonicalName;
+ }
+
+ protected override string Shorten()
+ {
+ return CanonicalName;
+ }
+
+ /// <summary>
+ /// Gets the canonical name of the reference this <see cref="FetchHead"/>
+ /// points to in the remote repository it's been fetched from.
+ /// </summary>
+ public virtual string RemoteCanonicalName { get; private set; }
+
+ /// <summary>
+ /// Gets the <see cref="GitObject"/> that this fetch head points to.
+ /// </summary>
+ public virtual GitObject Target
+ {
+ get { return TargetObject; }
+ }
+
+ /// <summary>
+ /// The URL of the remote repository this <see cref="FetchHead"/>
+ /// has been built from.
+ /// </summary>
+ public virtual String Url { get; private set; }
+
+ /// <summary>
+ /// Determines if this fetch head entry has been explicitly fetched.
+ /// </summary>
+ public virtual bool ForMerge { get; private set; }
+ }
+}
diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj
index b659dbcb..f30476e2 100644
--- a/LibGit2Sharp/LibGit2Sharp.csproj
+++ b/LibGit2Sharp/LibGit2Sharp.csproj
@@ -65,6 +65,7 @@
<Compile Include="Changes.cs" />
<Compile Include="CheckoutCallbacks.cs" />
<Compile Include="CheckoutOptions.cs" />
+ <Compile Include="Network.cs" />
<Compile Include="OrphanedHeadException.cs" />
<Compile Include="UnmergedIndexEntriesException.cs" />
<Compile Include="Commit.cs" />
@@ -89,6 +90,7 @@
<Compile Include="Credentials.cs" />
<Compile Include="DiffOptions.cs" />
<Compile Include="DiffTargets.cs" />
+ <Compile Include="FetchHead.cs" />
<Compile Include="Handlers.cs" />
<Compile Include="Ignore.cs" />
<Compile Include="MergeConflictException.cs" />
diff --git a/LibGit2Sharp/Network.cs b/LibGit2Sharp/Network.cs
new file mode 100644
index 00000000..859f73df
--- /dev/null
+++ b/LibGit2Sharp/Network.cs
@@ -0,0 +1,39 @@
+using System.Collections.Generic;
+using LibGit2Sharp.Core;
+
+namespace LibGit2Sharp
+{
+ /// <summary>
+ /// Provides access to network functionality for a repository.
+ /// </summary>
+ public class Network
+ {
+ private readonly Repository repository;
+
+ /// <summary>
+ /// Needed for mocking purposes.
+ /// </summary>
+ protected Network()
+ { }
+
+ internal Network(Repository repository)
+ {
+ this.repository = repository;
+ }
+
+ /// <summary>
+ /// The heads that have been updated during the last fetch.
+ /// </summary>
+ public virtual IEnumerable<FetchHead> FetchHeads
+ {
+ get
+ {
+ int i = 0;
+
+ return Proxy.git_repository_fetchhead_foreach(
+ repository.Handle,
+ (name, url, oid, isMerge) => new FetchHead(repository, name, url, new ObjectId(oid), isMerge, i++));
+ }
+ }
+ }
+}
diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs
index 1f4885a5..0ff084a0 100644
--- a/LibGit2Sharp/Repository.cs
+++ b/LibGit2Sharp/Repository.cs
@@ -31,6 +31,7 @@ namespace LibGit2Sharp
private readonly Diff diff;
private readonly NoteCollection notes;
private readonly Lazy<ObjectDatabase> odb;
+ private readonly Network network;
private readonly Stack<IDisposable> toCleanup = new Stack<IDisposable>();
private readonly Ignore ignore;
private static readonly Lazy<string> versionRetriever = new Lazy<string>(RetrieveVersion);
@@ -104,6 +105,7 @@ namespace LibGit2Sharp
diff = new Diff(this);
notes = new NoteCollection(this);
ignore = new Ignore(this);
+ network = new Network(this);
EagerlyLoadTheConfigIfAnyPathHaveBeenPassed(options);
}
@@ -199,6 +201,17 @@ namespace LibGit2Sharp
}
/// <summary>
+ /// Provides access to network functionality for a repository.
+ /// </summary>
+ public Network Network
+ {
+ get
+ {
+ return network;
+ }
+ }
+
+ /// <summary>
/// Gets the database.
/// </summary>
public ObjectDatabase ObjectDatabase