diff --git a/LibGit2Sharp.Tests/RemoteFixture.cs b/LibGit2Sharp.Tests/RemoteFixture.cs
index 8140508ef..dda9fdb01 100644
--- a/LibGit2Sharp.Tests/RemoteFixture.cs
+++ b/LibGit2Sharp.Tests/RemoteFixture.cs
@@ -103,7 +103,7 @@ public void CanFetchIntoAnEmptyRepository(string url)
}
// Perform the actual fetch
- remote.Fetch(new FetchProgress(), onUpdateTips: expectedFetchState.RemoteUpdateTipsHandler);
+ remote.Fetch(onUpdateTips: expectedFetchState.RemoteUpdateTipsHandler);
// Verify the expected
expectedFetchState.CheckUpdatedReferences(repo);
@@ -141,7 +141,7 @@ public void CanFetchAllTagsIntoAnEmptyRepository(string url)
}
// Perform the actual fetch
- remote.Fetch(new FetchProgress(), TagFetchMode.All, onUpdateTips: expectedFetchState.RemoteUpdateTipsHandler);
+ remote.Fetch(TagFetchMode.All, onUpdateTips: expectedFetchState.RemoteUpdateTipsHandler);
// Verify the expected
expectedFetchState.CheckUpdatedReferences(repo);
diff --git a/LibGit2Sharp/Core/GitTransferProgress.cs b/LibGit2Sharp/Core/GitTransferProgress.cs
new file mode 100644
index 000000000..b57dadf55
--- /dev/null
+++ b/LibGit2Sharp/Core/GitTransferProgress.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace LibGit2Sharp.Core
+{
+ ///
+ /// Managed structure corresponding to git_transfer_progress native structure.
+ ///
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct GitTransferProgress
+ {
+ public uint total_objects;
+ public uint indexed_objects;
+ public uint received_objects;
+ public UIntPtr received_bytes;
+ }
+}
diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs
index 06892dc0a..b47f58d82 100644
--- a/LibGit2Sharp/Core/NativeMethods.cs
+++ b/LibGit2Sharp/Core/NativeMethods.cs
@@ -784,7 +784,7 @@ internal static extern int git_tag_delete(
[DllImport(libgit2)]
internal static extern void git_threads_shutdown();
- internal delegate void git_transfer_progress_callback(IntPtr stats, IntPtr payload);
+ internal delegate void git_transfer_progress_callback(ref GitTransferProgress stats, IntPtr payload);
[DllImport(libgit2)]
internal static extern int git_tree_create_fromindex(out GitOid treeOid, IndexSafeHandle index);
diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs
index 823fca66d..d60ce2cb7 100644
--- a/LibGit2Sharp/Core/Proxy.cs
+++ b/LibGit2Sharp/Core/Proxy.cs
@@ -6,6 +6,7 @@
using System.Runtime.InteropServices;
using System.Threading;
using LibGit2Sharp.Core.Handles;
+using LibGit2Sharp.Handlers;
// ReSharper disable InconsistentNaming
namespace LibGit2Sharp.Core
@@ -1046,12 +1047,13 @@ public static void git_remote_disconnect(RemoteSafeHandle remote)
}
}
- // TODO: callback & payload
- public static void git_remote_download(RemoteSafeHandle remote, ref long bytes, ref GitIndexerStats indexerStats)
+ public static void git_remote_download(RemoteSafeHandle remote, TransferProgressHandler onTransferProgress)
{
using (ThreadAffinity())
{
- int res = NativeMethods.git_remote_download(remote, null, IntPtr.Zero);
+ NativeMethods.git_transfer_progress_callback cb = TransferCallbacks.GenerateCallback(onTransferProgress);
+
+ int res = NativeMethods.git_remote_download(remote, cb, IntPtr.Zero);
Ensure.Success(res);
}
}
diff --git a/LibGit2Sharp/FetchProgress.cs b/LibGit2Sharp/FetchProgress.cs
deleted file mode 100644
index 0f99bbc4d..000000000
--- a/LibGit2Sharp/FetchProgress.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-using LibGit2Sharp.Core;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading;
-
-namespace LibGit2Sharp
-{
- ///
- /// Contains data regarding fetch progress.
- ///
- public class FetchProgress
- {
- ///
- /// Fetch progress constructor.
- ///
- public FetchProgress()
- {
- IndexerStats = new IndexerStats();
- }
-
- ///
- /// Bytes received.
- ///
- public long Bytes
- {
- get
- {
- // read the bytes atomically
- return Interlocked.Read(ref bytes);
- }
- }
-
- ///
- /// The IndexerStats
- ///
- public IndexerStats IndexerStats { get; private set; }
-
- internal void Reset()
- {
- IndexerStats.Reset();
- bytes = 0;
- }
-
- #region Fields
-
- internal long bytes;
-
- #endregion
- }
-}
diff --git a/LibGit2Sharp/Handlers.cs b/LibGit2Sharp/Handlers.cs
index fca898048..bf88a4f73 100644
--- a/LibGit2Sharp/Handlers.cs
+++ b/LibGit2Sharp/Handlers.cs
@@ -1,12 +1,19 @@
using System;
+using LibGit2Sharp.Core;
namespace LibGit2Sharp.Handlers
{
///
- /// Delegate definition to handle Progress callback.
+ /// Delegate definition to handle Progress callback.
+ /// Returns the text as reported by the server. The text
+ /// in the serverProgressOutput parameter is not delivered
+ /// in any particular units (i.e. not necessarily delivered
+ /// as whole lines) and is likely to be chunked as partial lines.
///
- /// Progress message.
- public delegate void ProgressHandler(string message);
+ /// text reported by the server.
+ /// Text can be chunked at arbitrary increments (i.e. can be composed
+ /// of a partial line of text).
+ public delegate void ProgressHandler(string serverProgressOutput);
///
/// Delegate definition to handle UpdateTips callback.
@@ -23,4 +30,10 @@ namespace LibGit2Sharp.Handlers
///
///
public delegate int CompletionHandler(RemoteCompletionType RemoteCompletionType);
+
+ ///
+ /// Delegate definition for transfer progress callback.
+ ///
+ /// The object containing progress information.
+ public delegate void TransferProgressHandler(TransferProgress progress);
}
diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj
index 8de2023b4..f0d357f68 100644
--- a/LibGit2Sharp/LibGit2Sharp.csproj
+++ b/LibGit2Sharp/LibGit2Sharp.csproj
@@ -70,6 +70,7 @@
+
@@ -79,7 +80,6 @@
-
@@ -121,6 +121,8 @@
+
+
diff --git a/LibGit2Sharp/Remote.cs b/LibGit2Sharp/Remote.cs
index e5a43c2dd..32ee2a879 100644
--- a/LibGit2Sharp/Remote.cs
+++ b/LibGit2Sharp/Remote.cs
@@ -51,20 +51,19 @@ internal static Remote BuildFromPtr(RemoteSafeHandle handle, Repository repo)
///
/// Fetch from the .
///
- /// The datastructure where the progress of the fetch is reported.
/// Optional parameter indicating what tags to download.
/// Progress callback. Corresponds to libgit2 progress callback.
/// Completion callback. Corresponds to libgit2 completion callback.
/// UpdateTips callback. Corresponds to libgit2 update_tips callback.
- public virtual void Fetch(FetchProgress progress = null,
+ /// Callback method that transfer progress will be reported through.
+ /// Reports the client's state regarding the received and processed (bytes, objects) from the server.
+ public virtual void Fetch(
TagFetchMode tagFetchMode = TagFetchMode.Auto,
ProgressHandler onProgress = null,
CompletionHandler onCompletion = null,
- UpdateTipsHandler onUpdateTips = null)
+ UpdateTipsHandler onUpdateTips = null,
+ TransferProgressHandler onTransferProgress = null)
{
- progress = progress ?? new FetchProgress();
- progress.Reset();
-
using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, this.Name, true))
{
var callbacks = new RemoteCallbacks(onProgress, onCompletion, onUpdateTips);
@@ -85,8 +84,7 @@ public virtual void Fetch(FetchProgress progress = null,
try
{
Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch);
-
- Proxy.git_remote_download(remoteHandle, ref progress.bytes, ref progress.IndexerStats.gitIndexerStats);
+ Proxy.git_remote_download(remoteHandle, onTransferProgress);
}
finally
{
diff --git a/LibGit2Sharp/RepositoryExtensions.cs b/LibGit2Sharp/RepositoryExtensions.cs
index d59fbefdc..32572ae1f 100644
--- a/LibGit2Sharp/RepositoryExtensions.cs
+++ b/LibGit2Sharp/RepositoryExtensions.cs
@@ -151,22 +151,24 @@ public static Commit Commit(this IRepository repository, string message, Signatu
///
/// The being worked with.
/// The name of the to fetch from.
- /// The datastructure where the progress of the fetch is reported.
/// Optional parameter indicating what tags to download.
/// Progress callback. Corresponds to libgit2 progress callback.
/// Completion callback. Corresponds to libgit2 completion callback.
/// UpdateTips callback. Corresponds to libgit2 update_tips callback.
- public static void Fetch(this IRepository repository, string remoteName, FetchProgress progress = null,
+ /// Callback method that transfer progress will be reported through.
+ /// Reports the client's state regarding the received and processed (bytes, objects) from the server.
+ public static void Fetch(this IRepository repository, string remoteName,
TagFetchMode tagFetchMode = TagFetchMode.Auto,
ProgressHandler onProgress = null,
CompletionHandler onCompletion = null,
- UpdateTipsHandler onUpdateTips = null)
+ UpdateTipsHandler onUpdateTips = null,
+ TransferProgressHandler onTransferProgress = null)
{
Ensure.ArgumentNotNull(repository, "repository");
Ensure.ArgumentNotNullOrEmptyString(remoteName, "remoteName");
Remote remote = repository.Remotes.RemoteForName(remoteName, true);
- remote.Fetch(progress, tagFetchMode, onProgress, onCompletion, onUpdateTips);
+ remote.Fetch(tagFetchMode, onProgress, onCompletion, onUpdateTips, onTransferProgress);
}
private static Signature BuildSignatureFromGlobalConfiguration(IRepository repository, DateTimeOffset now)
diff --git a/LibGit2Sharp/TransferCallbacks.cs b/LibGit2Sharp/TransferCallbacks.cs
new file mode 100644
index 000000000..f5ccd8f52
--- /dev/null
+++ b/LibGit2Sharp/TransferCallbacks.cs
@@ -0,0 +1,54 @@
+using System;
+using LibGit2Sharp.Core;
+using LibGit2Sharp.Handlers;
+
+namespace LibGit2Sharp
+{
+ ///
+ /// Class to handle the mapping between libgit2 git_transfer_progress_callback function and
+ /// a corresponding . Generates a delegate that
+ /// wraps the delegate with a delegate that matches
+ /// the git_transfer_progress_callback signature.
+ ///
+ internal class TransferCallbacks
+ {
+ ///
+ /// Managed delegate to be called in response to a git_transfer_progress_callback callback from libgit2.
+ ///
+ private TransferProgressHandler onTransferProgress;
+
+ ///
+ /// Constructor to set up the native callback given managed delegate.
+ ///
+ /// The delegate that the git_transfer_progress_callback will call.
+ private TransferCallbacks(TransferProgressHandler onTransferProgress)
+ {
+ this.onTransferProgress = onTransferProgress;
+ }
+
+ ///
+ /// Generates a delegate that matches the native git_transfer_progress_callback function's signature and wraps the delegate.
+ ///
+ /// The delegate to call in responde to a the native git_transfer_progress_callback callback.
+ /// A delegate method with a signature that matches git_transfer_progress_callback.
+ internal static NativeMethods.git_transfer_progress_callback GenerateCallback(TransferProgressHandler onTransferProgress)
+ {
+ if (onTransferProgress == null)
+ {
+ return null;
+ }
+
+ return new TransferCallbacks(onTransferProgress).OnGitTransferProgress;
+ }
+
+ ///
+ /// The delegate with the signature that matches the native git_transfer_progress_callback function's signature.
+ ///
+ /// structure containing progress information.
+ /// Payload data.
+ private void OnGitTransferProgress(ref GitTransferProgress progress, IntPtr payload)
+ {
+ onTransferProgress(new TransferProgress(progress));
+ }
+ }
+}
diff --git a/LibGit2Sharp/TransferProgress.cs b/LibGit2Sharp/TransferProgress.cs
new file mode 100644
index 000000000..f3acfe679
--- /dev/null
+++ b/LibGit2Sharp/TransferProgress.cs
@@ -0,0 +1,71 @@
+using System;
+using LibGit2Sharp.Core;
+
+namespace LibGit2Sharp
+{
+ ///
+ /// Expose progress values from a fetch operation.
+ ///
+ public class TransferProgress
+ {
+ private GitTransferProgress gitTransferProgress;
+
+ ///
+ /// Empty constructor.
+ ///
+ protected TransferProgress()
+ { }
+
+ ///
+ /// Constructor.
+ ///
+ internal TransferProgress(GitTransferProgress gitTransferProgress)
+ {
+ this.gitTransferProgress = gitTransferProgress;
+ }
+
+ ///
+ /// Total number of objects.
+ ///
+ public virtual int TotalObjects
+ {
+ get
+ {
+ return (int) gitTransferProgress.total_objects;
+ }
+ }
+
+ ///
+ /// Number of objects indexed.
+ ///
+ public virtual int IndexedObjects
+ {
+ get
+ {
+ return (int) gitTransferProgress.indexed_objects;
+ }
+ }
+
+ ///
+ /// Number of objects received.
+ ///
+ public virtual int ReceivedObjects
+ {
+ get
+ {
+ return (int) gitTransferProgress.received_objects;
+ }
+ }
+
+ ///
+ /// Number of bytes received.
+ ///
+ public virtual long ReceivedBytes
+ {
+ get
+ {
+ return (long) gitTransferProgress.received_bytes;
+ }
+ }
+ }
+}