Skip to content

Commit fadfa10

Browse files
committed
Report Fetch progress through callbacks
1 parent 3191c1b commit fadfa10

File tree

11 files changed

+181
-74
lines changed

11 files changed

+181
-74
lines changed

LibGit2Sharp.Tests/RemoteFixture.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public void CanFetchIntoAnEmptyRepository(string url)
103103
}
104104

105105
// Perform the actual fetch
106-
remote.Fetch(new FetchProgress(), onUpdateTips: expectedFetchState.RemoteUpdateTipsHandler);
106+
remote.Fetch(onUpdateTips: expectedFetchState.RemoteUpdateTipsHandler);
107107

108108
// Verify the expected
109109
expectedFetchState.CheckUpdatedReferences(repo);
@@ -141,7 +141,7 @@ public void CanFetchAllTagsIntoAnEmptyRepository(string url)
141141
}
142142

143143
// Perform the actual fetch
144-
remote.Fetch(new FetchProgress(), TagFetchMode.All, onUpdateTips: expectedFetchState.RemoteUpdateTipsHandler);
144+
remote.Fetch(TagFetchMode.All, onUpdateTips: expectedFetchState.RemoteUpdateTipsHandler);
145145

146146
// Verify the expected
147147
expectedFetchState.CheckUpdatedReferences(repo);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
4+
namespace LibGit2Sharp.Core
5+
{
6+
/// <summary>
7+
/// Managed structure corresponding to git_transfer_progress native structure.
8+
/// </summary>
9+
[StructLayout(LayoutKind.Sequential)]
10+
internal struct GitTransferProgress
11+
{
12+
public uint total_objects;
13+
public uint indexed_objects;
14+
public uint received_objects;
15+
public UIntPtr received_bytes;
16+
}
17+
}

LibGit2Sharp/Core/NativeMethods.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,7 @@ internal static extern int git_tag_delete(
784784
[DllImport(libgit2)]
785785
internal static extern void git_threads_shutdown();
786786

787-
internal delegate void git_transfer_progress_callback(IntPtr stats, IntPtr payload);
787+
internal delegate void git_transfer_progress_callback(ref GitTransferProgress stats, IntPtr payload);
788788

789789
[DllImport(libgit2)]
790790
internal static extern int git_tree_create_fromindex(out GitOid treeOid, IndexSafeHandle index);

LibGit2Sharp/Core/Proxy.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Runtime.InteropServices;
77
using System.Threading;
88
using LibGit2Sharp.Core.Handles;
9+
using LibGit2Sharp.Handlers;
910

1011
// ReSharper disable InconsistentNaming
1112
namespace LibGit2Sharp.Core
@@ -1046,12 +1047,13 @@ public static void git_remote_disconnect(RemoteSafeHandle remote)
10461047
}
10471048
}
10481049

1049-
// TODO: callback & payload
1050-
public static void git_remote_download(RemoteSafeHandle remote, ref long bytes, ref GitIndexerStats indexerStats)
1050+
public static void git_remote_download(RemoteSafeHandle remote, TransferProgressHandler onTransferProgress)
10511051
{
10521052
using (ThreadAffinity())
10531053
{
1054-
int res = NativeMethods.git_remote_download(remote, null, IntPtr.Zero);
1054+
NativeMethods.git_transfer_progress_callback cb = TransferCallbacks.GenerateCallback(onTransferProgress);
1055+
1056+
int res = NativeMethods.git_remote_download(remote, cb, IntPtr.Zero);
10551057
Ensure.Success(res);
10561058
}
10571059
}

LibGit2Sharp/FetchProgress.cs

Lines changed: 0 additions & 52 deletions
This file was deleted.

LibGit2Sharp/Handlers.cs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
using System;
2+
using LibGit2Sharp.Core;
23

34
namespace LibGit2Sharp.Handlers
45
{
56
/// <summary>
6-
/// Delegate definition to handle Progress callback.
7+
/// Delegate definition to handle Progress callback.
8+
/// Returns the text as reported by the server. The text
9+
/// in the serverProgressOutput parameter is not delivered
10+
/// in any particular units (i.e. not necessarily delivered
11+
/// as whole lines) and is likely to be chunked as partial lines.
712
/// </summary>
8-
/// <param name="message">Progress message.</param>
9-
public delegate void ProgressHandler(string message);
13+
/// <param name="serverProgressOutput">text reported by the server.
14+
/// Text can be chunked at arbitrary increments (i.e. can be composed
15+
/// of a partial line of text).</param>
16+
public delegate void ProgressHandler(string serverProgressOutput);
1017

1118
/// <summary>
1219
/// Delegate definition to handle UpdateTips callback.
@@ -23,4 +30,10 @@ namespace LibGit2Sharp.Handlers
2330
/// <param name="RemoteCompletionType"></param>
2431
/// <returns></returns>
2532
public delegate int CompletionHandler(RemoteCompletionType RemoteCompletionType);
33+
34+
/// <summary>
35+
/// Delegate definition for transfer progress callback.
36+
/// </summary>
37+
/// <param name="progress">The <see cref = "TransferProgress" /> object containing progress information.</param>
38+
public delegate void TransferProgressHandler(TransferProgress progress);
2639
}

LibGit2Sharp/LibGit2Sharp.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
<Compile Include="ContentChanges.cs" />
7171
<Compile Include="Core\GitCheckoutOpts.cs" />
7272
<Compile Include="Core\GitConfigEntry.cs" />
73+
<Compile Include="Core\GitTransferProgress.cs" />
7374
<Compile Include="Core\Proxy.cs" />
7475
<Compile Include="Handlers.cs" />
7576
<Compile Include="ReferenceCollectionExtensions.cs" />
@@ -79,7 +80,6 @@
7980
<Compile Include="RemoteCompletionType.cs" />
8081
<Compile Include="TagCollectionExtensions.cs" />
8182
<Compile Include="Core\Compat\Environment.cs" />
82-
<Compile Include="FetchProgress.cs" />
8383
<Compile Include="Core\FilePath.cs" />
8484
<Compile Include="Core\FilePathExtensions.cs" />
8585
<Compile Include="Core\FilePathMarshaler.cs" />
@@ -121,6 +121,8 @@
121121
<Compile Include="Note.cs" />
122122
<Compile Include="RepositoryNotFoundException.cs" />
123123
<Compile Include="TagFetchMode.cs" />
124+
<Compile Include="TransferCallbacks.cs" />
125+
<Compile Include="TransferProgress.cs" />
124126
<Compile Include="TreeChanges.cs" />
125127
<Compile Include="TreeEntryChanges.cs" />
126128
<Compile Include="LibGit2SharpException.cs" />

LibGit2Sharp/Remote.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,19 @@ internal static Remote BuildFromPtr(RemoteSafeHandle handle, Repository repo)
5151
/// <summary>
5252
/// Fetch from the <see cref = "Remote" />.
5353
/// </summary>
54-
/// <param name="progress">The <see cref = "FetchProgress" /> datastructure where the progress of the fetch is reported.</param>
5554
/// <param name="tagFetchMode">Optional parameter indicating what tags to download.</param>
5655
/// <param name="onProgress">Progress callback. Corresponds to libgit2 progress callback.</param>
5756
/// <param name="onCompletion">Completion callback. Corresponds to libgit2 completion callback.</param>
5857
/// <param name="onUpdateTips">UpdateTips callback. Corresponds to libgit2 update_tips callback.</param>
59-
public virtual void Fetch(FetchProgress progress = null,
58+
/// <param name="onTransferProgress">Callback method that transfer progress will be reported through.
59+
/// Reports the client's state regarding the received and processed (bytes, objects) from the server.</param>
60+
public virtual void Fetch(
6061
TagFetchMode tagFetchMode = TagFetchMode.Auto,
6162
ProgressHandler onProgress = null,
6263
CompletionHandler onCompletion = null,
63-
UpdateTipsHandler onUpdateTips = null)
64+
UpdateTipsHandler onUpdateTips = null,
65+
TransferProgressHandler onTransferProgress = null)
6466
{
65-
progress = progress ?? new FetchProgress();
66-
progress.Reset();
67-
6867
using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, this.Name, true))
6968
{
7069
var callbacks = new RemoteCallbacks(onProgress, onCompletion, onUpdateTips);
@@ -85,8 +84,7 @@ public virtual void Fetch(FetchProgress progress = null,
8584
try
8685
{
8786
Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch);
88-
89-
Proxy.git_remote_download(remoteHandle, ref progress.bytes, ref progress.IndexerStats.gitIndexerStats);
87+
Proxy.git_remote_download(remoteHandle, onTransferProgress);
9088
}
9189
finally
9290
{

LibGit2Sharp/RepositoryExtensions.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,22 +151,24 @@ public static Commit Commit(this IRepository repository, string message, Signatu
151151
/// </summary>
152152
/// <param name="repository">The <see cref = "Repository" /> being worked with.</param>
153153
/// <param name="remoteName">The name of the <see cref="Remote"/> to fetch from.</param>
154-
/// <param name="progress">The <see cref = "FetchProgress" /> datastructure where the progress of the fetch is reported.</param>
155154
/// <param name="tagFetchMode">Optional parameter indicating what tags to download.</param>
156155
/// <param name="onProgress">Progress callback. Corresponds to libgit2 progress callback.</param>
157156
/// <param name="onCompletion">Completion callback. Corresponds to libgit2 completion callback.</param>
158157
/// <param name="onUpdateTips">UpdateTips callback. Corresponds to libgit2 update_tips callback.</param>
159-
public static void Fetch(this IRepository repository, string remoteName, FetchProgress progress = null,
158+
/// <param name="onTransferProgress">Callback method that transfer progress will be reported through.
159+
/// Reports the client's state regarding the received and processed (bytes, objects) from the server.</param>
160+
public static void Fetch(this IRepository repository, string remoteName,
160161
TagFetchMode tagFetchMode = TagFetchMode.Auto,
161162
ProgressHandler onProgress = null,
162163
CompletionHandler onCompletion = null,
163-
UpdateTipsHandler onUpdateTips = null)
164+
UpdateTipsHandler onUpdateTips = null,
165+
TransferProgressHandler onTransferProgress = null)
164166
{
165167
Ensure.ArgumentNotNull(repository, "repository");
166168
Ensure.ArgumentNotNullOrEmptyString(remoteName, "remoteName");
167169

168170
Remote remote = repository.Remotes.RemoteForName(remoteName, true);
169-
remote.Fetch(progress, tagFetchMode, onProgress, onCompletion, onUpdateTips);
171+
remote.Fetch(tagFetchMode, onProgress, onCompletion, onUpdateTips, onTransferProgress);
170172
}
171173

172174
private static Signature BuildSignatureFromGlobalConfiguration(IRepository repository, DateTimeOffset now)

LibGit2Sharp/TransferCallbacks.cs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System;
2+
using LibGit2Sharp.Core;
3+
using LibGit2Sharp.Handlers;
4+
5+
namespace LibGit2Sharp
6+
{
7+
/// <summary>
8+
/// Class to handle the mapping between libgit2 git_transfer_progress_callback function and
9+
/// a corresponding <see cref = "TransferProgressHandler" />. Generates a delegate that
10+
/// wraps the <see cref = "TransferProgressHandler" /> delegate with a delegate that matches
11+
/// the git_transfer_progress_callback signature.
12+
/// </summary>
13+
internal class TransferCallbacks
14+
{
15+
/// <summary>
16+
/// Managed delegate to be called in response to a git_transfer_progress_callback callback from libgit2.
17+
/// </summary>
18+
private TransferProgressHandler onTransferProgress;
19+
20+
/// <summary>
21+
/// Constructor to set up the native callback given managed delegate.
22+
/// </summary>
23+
/// <param name="onTransferProgress">The <see cref="TransferProgressHandler"/> delegate that the git_transfer_progress_callback will call.</param>
24+
private TransferCallbacks(TransferProgressHandler onTransferProgress)
25+
{
26+
this.onTransferProgress = onTransferProgress;
27+
}
28+
29+
/// <summary>
30+
/// Generates a delegate that matches the native git_transfer_progress_callback function's signature and wraps the <see cref = "TransferProgressHandler" /> delegate.
31+
/// </summary>
32+
/// <param name="onTransferProgress">The <see cref = "TransferProgressHandler" /> delegate to call in responde to a the native git_transfer_progress_callback callback.</param>
33+
/// <returns>A delegate method with a signature that matches git_transfer_progress_callback.</returns>
34+
internal static NativeMethods.git_transfer_progress_callback GenerateCallback(TransferProgressHandler onTransferProgress)
35+
{
36+
if (onTransferProgress == null)
37+
{
38+
return null;
39+
}
40+
41+
return new TransferCallbacks(onTransferProgress).OnGitTransferProgress;
42+
}
43+
44+
/// <summary>
45+
/// The delegate with the signature that matches the native git_transfer_progress_callback function's signature.
46+
/// </summary>
47+
/// <param name="progress"><see cref = "GitTransferProgress" /> structure containing progress information.</param>
48+
/// <param name="payload">Payload data.</param>
49+
private void OnGitTransferProgress(ref GitTransferProgress progress, IntPtr payload)
50+
{
51+
onTransferProgress(new TransferProgress(progress));
52+
}
53+
}
54+
}

LibGit2Sharp/TransferProgress.cs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using System;
2+
using LibGit2Sharp.Core;
3+
4+
namespace LibGit2Sharp
5+
{
6+
/// <summary>
7+
/// Expose progress values from a fetch operation.
8+
/// </summary>
9+
public class TransferProgress
10+
{
11+
private GitTransferProgress gitTransferProgress;
12+
13+
/// <summary>
14+
/// Empty constructor.
15+
/// </summary>
16+
protected TransferProgress()
17+
{ }
18+
19+
/// <summary>
20+
/// Constructor.
21+
/// </summary>
22+
internal TransferProgress(GitTransferProgress gitTransferProgress)
23+
{
24+
this.gitTransferProgress = gitTransferProgress;
25+
}
26+
27+
/// <summary>
28+
/// Total number of objects.
29+
/// </summary>
30+
public virtual int TotalObjects
31+
{
32+
get
33+
{
34+
return (int) gitTransferProgress.total_objects;
35+
}
36+
}
37+
38+
/// <summary>
39+
/// Number of objects indexed.
40+
/// </summary>
41+
public virtual int IndexedObjects
42+
{
43+
get
44+
{
45+
return (int) gitTransferProgress.indexed_objects;
46+
}
47+
}
48+
49+
/// <summary>
50+
/// Number of objects received.
51+
/// </summary>
52+
public virtual int ReceivedObjects
53+
{
54+
get
55+
{
56+
return (int) gitTransferProgress.received_objects;
57+
}
58+
}
59+
60+
/// <summary>
61+
/// Number of bytes received.
62+
/// </summary>
63+
public virtual long ReceivedBytes
64+
{
65+
get
66+
{
67+
return (long) gitTransferProgress.received_bytes;
68+
}
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)