From 981f43909ca79b3b9e5c5a34590d76ecd5c82e3f Mon Sep 17 00:00:00 2001 From: Jameson Miller Date: Fri, 18 Oct 2013 13:22:58 -0400 Subject: [PATCH 1/2] Expose Push progress reporting --- LibGit2Sharp.Tests/PushFixture.cs | 13 +++- LibGit2Sharp/Core/NativeMethods.cs | 12 +++ LibGit2Sharp/Core/PackbuilderCallbacks.cs | 39 ++++++++++ LibGit2Sharp/Core/Proxy.cs | 11 +++ .../Core/PushTransferProgressCallbacks.cs | 38 +++++++++ LibGit2Sharp/Handlers.cs | 34 ++++++++ LibGit2Sharp/LibGit2Sharp.csproj | 2 + LibGit2Sharp/Network.cs | 20 ++--- LibGit2Sharp/NetworkExtensions.cs | 78 +------------------ LibGit2Sharp/PushOptions.cs | 15 ++++ 10 files changed, 176 insertions(+), 86 deletions(-) create mode 100644 LibGit2Sharp/Core/PackbuilderCallbacks.cs create mode 100644 LibGit2Sharp/Core/PushTransferProgressCallbacks.cs diff --git a/LibGit2Sharp.Tests/PushFixture.cs b/LibGit2Sharp.Tests/PushFixture.cs index af26b7577..2b836e457 100644 --- a/LibGit2Sharp.Tests/PushFixture.cs +++ b/LibGit2Sharp.Tests/PushFixture.cs @@ -60,9 +60,20 @@ private void AssertPush(Action push) [Fact] public void CanPushABranchTrackingAnUpstreamBranch() { + bool packBuilderCalled = false; + Handlers.PackBuilderProgressHandler packBuilderCb = (x, y, z) => { packBuilderCalled = true; return false; }; + AssertPush(repo => repo.Network.Push(repo.Head)); AssertPush(repo => repo.Network.Push(repo.Branches["master"])); - AssertPush(repo => repo.Network.Push(repo.Network.Remotes["origin"], "HEAD", @"refs/heads/master", OnPushStatusError)); + + PushOptions options = new PushOptions() + { + OnPushStatusError = OnPushStatusError, + OnPackBuilderProgress = packBuilderCb, + }; + + AssertPush(repo => repo.Network.Push(repo.Network.Remotes["origin"], "HEAD", @"refs/heads/master", options)); + Assert.True(packBuilderCalled); } [Fact] diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs index c84c99110..57ef92df8 100644 --- a/LibGit2Sharp/Core/NativeMethods.cs +++ b/LibGit2Sharp/Core/NativeMethods.cs @@ -626,6 +626,18 @@ internal static extern int git_object_peel( [DllImport(libgit2)] internal static extern int git_push_new(out PushSafeHandle push, RemoteSafeHandle remote); + /* Push network progress notification function */ + internal delegate int git_push_transfer_progress(uint current, uint total, UIntPtr bytes, IntPtr payload); + internal delegate int git_packbuilder_progress(int stage, uint current, uint total, IntPtr payload); + + [DllImport(libgit2)] + internal static extern int git_push_set_callbacks( + PushSafeHandle push, + git_packbuilder_progress pack_progress_cb, + IntPtr pack_progress_cb_payload, + git_push_transfer_progress transfer_progress_cb, + IntPtr transfer_progress_cb_payload); + [DllImport(libgit2)] internal static extern int git_push_set_options(PushSafeHandle push, GitPushOptions options); diff --git a/LibGit2Sharp/Core/PackbuilderCallbacks.cs b/LibGit2Sharp/Core/PackbuilderCallbacks.cs new file mode 100644 index 000000000..880748c31 --- /dev/null +++ b/LibGit2Sharp/Core/PackbuilderCallbacks.cs @@ -0,0 +1,39 @@ +using System; +using LibGit2Sharp.Handlers; + +namespace LibGit2Sharp.Core +{ + // + internal class PackbuilderCallbacks + { + private readonly PackBuilderProgressHandler onPackBuilderProgress; + + /// S + /// Constructor to set up the native callback given managed delegate. + /// + /// The delegate that the git_packbuilder_progress will call. + internal PackbuilderCallbacks(PackBuilderProgressHandler onPackBuilderProgress) + { + this.onPackBuilderProgress = onPackBuilderProgress; + } + + /// + /// Generates a delegate that matches the native git_packbuilder_progress function's signature and wraps the delegate. + /// + /// A delegate method with a signature that matches git_transfer_progress_callback. + internal NativeMethods.git_packbuilder_progress GenerateCallback() + { + if (onPackBuilderProgress == null) + { + return null; + } + + return new PackbuilderCallbacks(onPackBuilderProgress).OnGitPackBuilderProgress; + } + + private int OnGitPackBuilderProgress(int stage, uint current, uint total, IntPtr payload) + { + return onPackBuilderProgress((PackBuilderStage) stage, (int)current, (int)total) ? -1 : 0; + } + } +} diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs index 5fdd63906..3cd16b8bd 100644 --- a/LibGit2Sharp/Core/Proxy.cs +++ b/LibGit2Sharp/Core/Proxy.cs @@ -1134,6 +1134,17 @@ public static PushSafeHandle git_push_new(RemoteSafeHandle remote) return handle; } } + public static void git_push_set_callbacks( + PushSafeHandle push, + NativeMethods.git_push_transfer_progress pushTransferProgress, + NativeMethods.git_packbuilder_progress packBuilderProgress) + { + using (ThreadAffinity()) + { + int res = NativeMethods.git_push_set_callbacks(push, packBuilderProgress, IntPtr.Zero, pushTransferProgress, IntPtr.Zero); + Ensure.ZeroResult(res); + } + } public static void git_push_set_options(PushSafeHandle push, GitPushOptions options) { diff --git a/LibGit2Sharp/Core/PushTransferProgressCallbacks.cs b/LibGit2Sharp/Core/PushTransferProgressCallbacks.cs new file mode 100644 index 000000000..b5cee8420 --- /dev/null +++ b/LibGit2Sharp/Core/PushTransferProgressCallbacks.cs @@ -0,0 +1,38 @@ +using System; +using LibGit2Sharp.Handlers; + +namespace LibGit2Sharp.Core +{ + internal class PushTransferCallbacks + { + private readonly PushTransferProgressHandler onPushTransferProgress; + + /// + /// Constructor to set up the native callback given managed delegate. + /// + /// The delegate that the git_transfer_progress_callback will call. + internal PushTransferCallbacks(PushTransferProgressHandler onPushTransferProgress) + { + this.onPushTransferProgress = onPushTransferProgress; + } + + /// + /// Generates a delegate that matches the native git_transfer_progress_callback function's signature and wraps the delegate. + /// + /// A delegate method with a signature that matches git_transfer_progress_callback. + internal NativeMethods.git_push_transfer_progress GenerateCallback() + { + if (onPushTransferProgress == null) + { + return null; + } + + return new PushTransferCallbacks(onPushTransferProgress).OnGitTransferProgress; + } + + private int OnGitTransferProgress(uint current, uint total, UIntPtr bytes, IntPtr payload) + { + return onPushTransferProgress((int)current, (int)total, (long)bytes) ? -1 : 0; + } + } +} diff --git a/LibGit2Sharp/Handlers.cs b/LibGit2Sharp/Handlers.cs index 4d8ceefe4..85e0dd9e5 100644 --- a/LibGit2Sharp/Handlers.cs +++ b/LibGit2Sharp/Handlers.cs @@ -33,6 +33,24 @@ /// Return negative integer to cancel. public delegate int TransferProgressHandler(TransferProgress progress); + /// + /// Delegate definition for callback reporting push network progress. + /// + /// The current number of objects sent to server. + /// The total number of objects to send to the server. + /// The number of bytes sent to the server. + /// True to cancel. + public delegate bool PushTransferProgressHandler(int current, int total, long bytes); + + /// + /// Delegate definition for callback reporting pack builder progress. + /// + /// The current stage progress is being reported for. + /// The current number of objects processed in this this stage. + /// The total number of objects to process for the current stage. + /// True to cancel. + public delegate bool PackBuilderProgressHandler(PackBuilderStage stage, int current, int total); + /// /// Delegate definition to handle reporting errors when updating references on the remote. /// @@ -63,4 +81,20 @@ /// /// The unmatched path. public delegate void UnmatchedPathHandler(string unmatchedPath); + + /// + /// The stages of pack building. + /// + public enum PackBuilderStage + { + /// + /// Counting stage. + /// + Counting, + + /// + /// Deltafying stage. + /// + Deltafying + } } diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj index 620847f10..2e9b9d340 100644 --- a/LibGit2Sharp/LibGit2Sharp.csproj +++ b/LibGit2Sharp/LibGit2Sharp.csproj @@ -72,6 +72,8 @@ + + diff --git a/LibGit2Sharp/Network.cs b/LibGit2Sharp/Network.cs index b77cb8792..7b69a37b6 100644 --- a/LibGit2Sharp/Network.cs +++ b/LibGit2Sharp/Network.cs @@ -150,13 +150,11 @@ public virtual void Fetch( /// The to push to. /// The source objectish to push. /// The reference to update on the remote. - /// Handler for reporting failed push updates. /// controlling push behavior public virtual void Push( Remote remote, string objectish, string destinationSpec, - PushStatusErrorHandler onPushStatusError, PushOptions pushOptions = null) { Ensure.ArgumentNotNull(remote, "remote"); @@ -164,7 +162,7 @@ public virtual void Push( Ensure.ArgumentNotNullOrEmptyString(destinationSpec, destinationSpec); Push(remote, string.Format(CultureInfo.InvariantCulture, - "{0}:{1}", objectish, destinationSpec), onPushStatusError, pushOptions); + "{0}:{1}", objectish, destinationSpec), pushOptions); } /// @@ -172,18 +170,16 @@ public virtual void Push( /// /// The to push to. /// The pushRefSpec to push. - /// Handler for reporting failed push updates. /// controlling push behavior public virtual void Push( Remote remote, string pushRefSpec, - PushStatusErrorHandler onPushStatusError, PushOptions pushOptions = null) { Ensure.ArgumentNotNull(remote, "remote"); Ensure.ArgumentNotNullOrEmptyString(pushRefSpec, "pushRefSpec"); - Push(remote, new string[] { pushRefSpec }, onPushStatusError, pushOptions); + Push(remote, new string[] { pushRefSpec }, pushOptions); } /// @@ -191,12 +187,10 @@ public virtual void Push( /// /// The to push to. /// The pushRefSpecs to push. - /// Handler for reporting failed push updates. /// controlling push behavior public virtual void Push( Remote remote, IEnumerable pushRefSpecs, - PushStatusErrorHandler onPushStatusError, PushOptions pushOptions = null) { Ensure.ArgumentNotNull(remote, "remote"); @@ -213,7 +207,7 @@ public virtual void Push( pushOptions = new PushOptions(); } - PushCallbacks pushStatusUpdates = new PushCallbacks(onPushStatusError); + PushCallbacks pushStatusUpdates = new PushCallbacks(pushOptions.OnPushStatusError); // Load the remote. using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, remote.Name, true)) @@ -229,6 +223,14 @@ public virtual void Push( // Perform the actual push. using (PushSafeHandle pushHandle = Proxy.git_push_new(remoteHandle)) { + PushTransferCallbacks pushTransferCallbacks = new PushTransferCallbacks(pushOptions.OnPushTransferProgress); + PackbuilderCallbacks packBuilderCallbacks = new PackbuilderCallbacks(pushOptions.OnPackBuilderProgress); + + NativeMethods.git_push_transfer_progress pushProgress = pushTransferCallbacks.GenerateCallback(); + NativeMethods.git_packbuilder_progress packBuilderProgress = packBuilderCallbacks.GenerateCallback(); + + Proxy.git_push_set_callbacks(pushHandle, pushProgress, packBuilderProgress); + // Set push options. Proxy.git_push_set_options(pushHandle, new GitPushOptions() diff --git a/LibGit2Sharp/NetworkExtensions.cs b/LibGit2Sharp/NetworkExtensions.cs index 59493b827..943ecac8e 100644 --- a/LibGit2Sharp/NetworkExtensions.cs +++ b/LibGit2Sharp/NetworkExtensions.cs @@ -25,7 +25,7 @@ public static void Push( PushStatusErrorHandler onPushStatusError = null, PushOptions pushOptions = null) { - network.Push(new[] { branch }, onPushStatusError, pushOptions); + network.Push(new[] { branch }, pushOptions); } /// @@ -33,13 +33,11 @@ public static void Push( /// /// The being worked with. /// The branches to push. - /// Handler for reporting failed push updates. /// controlling push behavior /// Throws if either the Remote or the UpstreamBranchCanonicalName is not set. public static void Push( this Network network, IEnumerable branches, - PushStatusErrorHandler onPushStatusError = null, PushOptions pushOptions = null) { var enumeratedBranches = branches as IList ?? branches.ToList(); @@ -55,80 +53,8 @@ public static void Push( foreach (var branch in enumeratedBranches) { - network.Push(branch.Remote, string.Format("{0}:{1}", branch.CanonicalName, branch.UpstreamBranchCanonicalName), onPushStatusError, pushOptions); + network.Push(branch.Remote, string.Format("{0}:{1}", branch.CanonicalName, branch.UpstreamBranchCanonicalName), pushOptions); } } - - /// - /// Push the objectish to the destination reference on the . - /// - /// The being worked with. - /// The to push to. - /// The source objectish to push. - /// The reference to update on the remote. - /// controlling push behavior - /// Results of the push operation. - public static PushResult Push( - this Network network, - Remote remote, - string objectish, - string destinationSpec, - PushOptions pushOptions = null) - { - Ensure.ArgumentNotNull(remote, "remote"); - Ensure.ArgumentNotNull(objectish, "objectish"); - Ensure.ArgumentNotNullOrEmptyString(destinationSpec, "destinationSpec"); - - return network.Push(remote, string.Format(CultureInfo.InvariantCulture, - "{0}:{1}", objectish, destinationSpec), pushOptions); - } - - /// - /// Push specified reference to the . - /// - /// The being worked with. - /// The to push to. - /// The pushRefSpec to push. - /// controlling push behavior - /// Results of the push operation. - public static PushResult Push( - this Network network, - Remote remote, - string pushRefSpec, - PushOptions pushOptions = null) - { - Ensure.ArgumentNotNull(remote, "remote"); - Ensure.ArgumentNotNullOrEmptyString(pushRefSpec, "pushRefSpec"); - - return network.Push(remote, new string[] { pushRefSpec }, pushOptions); - } - - /// - /// Push specified references to the . - /// - /// The being worked with. - /// The to push to. - /// The pushRefSpecs to push. - /// controlling push behavior - /// Results of the push operation. - public static PushResult Push( - this Network network, - Remote remote, - IEnumerable pushRefSpecs, - PushOptions pushOptions = null) - { - Ensure.ArgumentNotNull(remote, "remote"); - Ensure.ArgumentNotNull(pushRefSpecs, "pushRefSpecs"); - - var failedRemoteUpdates = new List(); - - network.Push( - remote, - pushRefSpecs, - failedRemoteUpdates.Add, - pushOptions); - - return new PushResult(failedRemoteUpdates); - } } } diff --git a/LibGit2Sharp/PushOptions.cs b/LibGit2Sharp/PushOptions.cs index 0799877bf..5306f8517 100644 --- a/LibGit2Sharp/PushOptions.cs +++ b/LibGit2Sharp/PushOptions.cs @@ -20,5 +20,20 @@ public sealed class PushOptions /// the number of threads to create. /// public int PackbuilderDegreeOfParallelism { get; set; } + + /// + /// Delegate to report errors when updating references on the remote. + /// + public PushStatusErrorHandler OnPushStatusError { get; set; } + + /// + /// Delegate to report push network transfer progress. + /// + public PushTransferProgressHandler OnPushTransferProgress { get; set; } + + /// + /// Delagate to report pack builder progress. + /// + public PackBuilderProgressHandler OnPackBuilderProgress { get; set; } } } From bd736e2d130bd441fe7e767d9a7289d720bd0aea Mon Sep 17 00:00:00 2001 From: Jameson Miller Date: Fri, 18 Oct 2013 14:56:24 -0400 Subject: [PATCH 2/2] Clean up cancellation patterns in callbacks and other small cleanups. --- LibGit2Sharp.Tests/CloneFixture.cs | 2 +- LibGit2Sharp.Tests/PushFixture.cs | 2 +- .../TestHelpers/ExpectedFetchState.cs | 6 +-- LibGit2Sharp/CheckoutCallbacks.cs | 6 +-- LibGit2Sharp/Core/PackbuilderCallbacks.cs | 3 +- LibGit2Sharp/Core/Proxy.cs | 14 ++++++ .../Core/PushTransferProgressCallbacks.cs | 2 +- LibGit2Sharp/Handlers.cs | 17 +++---- LibGit2Sharp/Network.cs | 8 ++-- LibGit2Sharp/NetworkExtensions.cs | 2 - LibGit2Sharp/PushOptions.cs | 8 +++- LibGit2Sharp/RemoteCallbacks.cs | 45 +++---------------- LibGit2Sharp/Repository.cs | 2 +- LibGit2Sharp/RepositoryExtensions.cs | 4 +- 14 files changed, 47 insertions(+), 74 deletions(-) diff --git a/LibGit2Sharp.Tests/CloneFixture.cs b/LibGit2Sharp.Tests/CloneFixture.cs index 800ccc2f8..10e010348 100644 --- a/LibGit2Sharp.Tests/CloneFixture.cs +++ b/LibGit2Sharp.Tests/CloneFixture.cs @@ -116,7 +116,7 @@ public void CallsProgressCallbacks(string url) var scd = BuildSelfCleaningDirectory(); Repository.Clone(url, scd.DirectoryPath, - onTransferProgress: _ => { transferWasCalled = true; return 0; }, + onTransferProgress: _ => { transferWasCalled = true; return true; }, onCheckoutProgress: (a, b, c) => checkoutWasCalled = true); Assert.True(transferWasCalled); diff --git a/LibGit2Sharp.Tests/PushFixture.cs b/LibGit2Sharp.Tests/PushFixture.cs index 2b836e457..e4afc8031 100644 --- a/LibGit2Sharp.Tests/PushFixture.cs +++ b/LibGit2Sharp.Tests/PushFixture.cs @@ -61,7 +61,7 @@ private void AssertPush(Action push) public void CanPushABranchTrackingAnUpstreamBranch() { bool packBuilderCalled = false; - Handlers.PackBuilderProgressHandler packBuilderCb = (x, y, z) => { packBuilderCalled = true; return false; }; + Handlers.PackBuilderProgressHandler packBuilderCb = (x, y, z) => { packBuilderCalled = true; return true; }; AssertPush(repo => repo.Network.Push(repo.Head)); AssertPush(repo => repo.Network.Push(repo.Branches["master"])); diff --git a/LibGit2Sharp.Tests/TestHelpers/ExpectedFetchState.cs b/LibGit2Sharp.Tests/TestHelpers/ExpectedFetchState.cs index 722b88730..78a3e682f 100644 --- a/LibGit2Sharp.Tests/TestHelpers/ExpectedFetchState.cs +++ b/LibGit2Sharp.Tests/TestHelpers/ExpectedFetchState.cs @@ -78,8 +78,8 @@ public void AddExpectedTag(string tagName, ObjectId oldId, TestRemoteInfo.Expect /// Name of reference being updated. /// Old ID of reference. /// New ID of reference. - /// 0 on success; a negative value to abort the process. - public int RemoteUpdateTipsHandler(string referenceName, ObjectId oldId, ObjectId newId) + /// True to continue, false to cancel. + public bool RemoteUpdateTipsHandler(string referenceName, ObjectId oldId, ObjectId newId) { // assert that we have not seen this reference before Assert.DoesNotContain(referenceName, ObservedReferenceUpdates.Keys); @@ -97,7 +97,7 @@ public int RemoteUpdateTipsHandler(string referenceName, ObjectId oldId, ObjectI Assert.Equal(referenceUpdate.NewId, newId); } - return 0; + return true; } /// diff --git a/LibGit2Sharp/CheckoutCallbacks.cs b/LibGit2Sharp/CheckoutCallbacks.cs index 93f2b3b78..fa8817b81 100644 --- a/LibGit2Sharp/CheckoutCallbacks.cs +++ b/LibGit2Sharp/CheckoutCallbacks.cs @@ -100,14 +100,14 @@ private int OnGitCheckoutNotify( IntPtr workdirPtr, IntPtr payloadPtr) { - int result = 0; + bool result = true; if (this.onCheckoutNotify != null) { FilePath path = LaxFilePathMarshaler.FromNative(pathPtr) ?? FilePath.Empty; - result = onCheckoutNotify(path.Native, why) ? 0 : 1; + result = onCheckoutNotify(path.Native, why); } - return result; + return Proxy.ConvertResultToCancelFlag(result); } } } diff --git a/LibGit2Sharp/Core/PackbuilderCallbacks.cs b/LibGit2Sharp/Core/PackbuilderCallbacks.cs index 880748c31..7c496654c 100644 --- a/LibGit2Sharp/Core/PackbuilderCallbacks.cs +++ b/LibGit2Sharp/Core/PackbuilderCallbacks.cs @@ -3,7 +3,6 @@ namespace LibGit2Sharp.Core { - // internal class PackbuilderCallbacks { private readonly PackBuilderProgressHandler onPackBuilderProgress; @@ -33,7 +32,7 @@ internal NativeMethods.git_packbuilder_progress GenerateCallback() private int OnGitPackBuilderProgress(int stage, uint current, uint total, IntPtr payload) { - return onPackBuilderProgress((PackBuilderStage) stage, (int)current, (int)total) ? -1 : 0; + return Proxy.ConvertResultToCancelFlag(onPackBuilderProgress((PackBuilderStage)stage, (int)current, (int)total)); } } } diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs index 3cd16b8bd..86a542284 100644 --- a/LibGit2Sharp/Core/Proxy.cs +++ b/LibGit2Sharp/Core/Proxy.cs @@ -1134,6 +1134,7 @@ public static PushSafeHandle git_push_new(RemoteSafeHandle remote) return handle; } } + public static void git_push_set_callbacks( PushSafeHandle push, NativeMethods.git_push_transfer_progress pushTransferProgress, @@ -2524,6 +2525,19 @@ public void Dispose() { typeof(bool), value => git_config_parse_bool(value) }, { typeof(string), value => value }, }; + + /// + /// Helper method for consistent conversion of return value on + /// Callbacks that support cancellation from bool to native type. + /// True indicates that function should continue, false indicates + /// user wants to cancel. + /// + /// + /// + internal static int ConvertResultToCancelFlag(bool result) + { + return result ? 0 : -1; + } } } // ReSharper restore InconsistentNaming diff --git a/LibGit2Sharp/Core/PushTransferProgressCallbacks.cs b/LibGit2Sharp/Core/PushTransferProgressCallbacks.cs index b5cee8420..2d40bf687 100644 --- a/LibGit2Sharp/Core/PushTransferProgressCallbacks.cs +++ b/LibGit2Sharp/Core/PushTransferProgressCallbacks.cs @@ -32,7 +32,7 @@ internal NativeMethods.git_push_transfer_progress GenerateCallback() private int OnGitTransferProgress(uint current, uint total, UIntPtr bytes, IntPtr payload) { - return onPushTransferProgress((int)current, (int)total, (long)bytes) ? -1 : 0; + return Proxy.ConvertResultToCancelFlag(onPushTransferProgress((int)current, (int)total, (long)bytes)); } } } diff --git a/LibGit2Sharp/Handlers.cs b/LibGit2Sharp/Handlers.cs index 85e0dd9e5..f6a798cbe 100644 --- a/LibGit2Sharp/Handlers.cs +++ b/LibGit2Sharp/Handlers.cs @@ -18,20 +18,15 @@ /// Name of the updated reference. /// Old ID of the reference. /// New ID of the reference. - /// Return negative integer to cancel. - public delegate int UpdateTipsHandler(string referenceName, ObjectId oldId, ObjectId newId); - - /// - /// Delegate definition to handle Completion callback. - /// - public delegate int CompletionHandler(RemoteCompletionType remoteCompletionType); + /// True to continue, false to cancel. + public delegate bool UpdateTipsHandler(string referenceName, ObjectId oldId, ObjectId newId); /// /// Delegate definition for transfer progress callback. /// /// The object containing progress information. - /// Return negative integer to cancel. - public delegate int TransferProgressHandler(TransferProgress progress); + /// True to continue, false to cancel. + public delegate bool TransferProgressHandler(TransferProgress progress); /// /// Delegate definition for callback reporting push network progress. @@ -39,7 +34,7 @@ /// The current number of objects sent to server. /// The total number of objects to send to the server. /// The number of bytes sent to the server. - /// True to cancel. + /// True to continue, false to cancel. public delegate bool PushTransferProgressHandler(int current, int total, long bytes); /// @@ -48,7 +43,7 @@ /// The current stage progress is being reported for. /// The current number of objects processed in this this stage. /// The total number of objects to process for the current stage. - /// True to cancel. + /// True to continue, false to cancel. public delegate bool PackBuilderProgressHandler(PackBuilderStage stage, int current, int total); /// diff --git a/LibGit2Sharp/Network.cs b/LibGit2Sharp/Network.cs index 7b69a37b6..d74fb8cb7 100644 --- a/LibGit2Sharp/Network.cs +++ b/LibGit2Sharp/Network.cs @@ -95,7 +95,6 @@ public virtual IEnumerable ListReferences(Remote remote) /// The remote to fetch /// 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. /// Callback method that transfer progress will be reported through. /// Reports the client's state regarding the received and processed (bytes, objects) from the server. @@ -104,7 +103,6 @@ public virtual void Fetch( Remote remote, TagFetchMode? tagFetchMode = null, ProgressHandler onProgress = null, - CompletionHandler onCompletion = null, UpdateTipsHandler onUpdateTips = null, TransferProgressHandler onTransferProgress = null, Credentials credentials = null) @@ -113,7 +111,7 @@ public virtual void Fetch( using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, remote.Name, true)) { - var callbacks = new RemoteCallbacks(onProgress, onTransferProgress, onCompletion, onUpdateTips, credentials); + var callbacks = new RemoteCallbacks(onProgress, onTransferProgress, onUpdateTips, credentials); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); if (tagFetchMode.HasValue) @@ -212,7 +210,7 @@ public virtual void Push( // Load the remote. using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, remote.Name, true)) { - var callbacks = new RemoteCallbacks(null, null, null, null, pushOptions.Credentials); + var callbacks = new RemoteCallbacks(null, null, null, pushOptions.Credentials); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); Proxy.git_remote_set_callbacks(remoteHandle, ref gitCallbacks); @@ -228,7 +226,7 @@ public virtual void Push( NativeMethods.git_push_transfer_progress pushProgress = pushTransferCallbacks.GenerateCallback(); NativeMethods.git_packbuilder_progress packBuilderProgress = packBuilderCallbacks.GenerateCallback(); - + Proxy.git_push_set_callbacks(pushHandle, pushProgress, packBuilderProgress); // Set push options. diff --git a/LibGit2Sharp/NetworkExtensions.cs b/LibGit2Sharp/NetworkExtensions.cs index 943ecac8e..6016aafa4 100644 --- a/LibGit2Sharp/NetworkExtensions.cs +++ b/LibGit2Sharp/NetworkExtensions.cs @@ -16,13 +16,11 @@ public static class NetworkExtensions /// /// The being worked with. /// The branch to push. - /// Handler for reporting failed push updates. /// controlling push behavior /// Throws if either the Remote or the UpstreamBranchCanonicalName is not set. public static void Push( this Network network, Branch branch, - PushStatusErrorHandler onPushStatusError = null, PushOptions pushOptions = null) { network.Push(new[] { branch }, pushOptions); diff --git a/LibGit2Sharp/PushOptions.cs b/LibGit2Sharp/PushOptions.cs index 5306f8517..db998ff29 100644 --- a/LibGit2Sharp/PushOptions.cs +++ b/LibGit2Sharp/PushOptions.cs @@ -27,12 +27,16 @@ public sealed class PushOptions public PushStatusErrorHandler OnPushStatusError { get; set; } /// - /// Delegate to report push network transfer progress. + /// Delegate that progress updates of the network transfer portion of push + /// will be reported through. The frequency of progress updates will not + /// be more than once every 0.5 seconds (in general). /// public PushTransferProgressHandler OnPushTransferProgress { get; set; } /// - /// Delagate to report pack builder progress. + /// Delegate that progress updates of the pack building portion of push + /// will be reported through. The frequency of progress updates will not + /// be more than once every 0.5 seconds (in general). /// public PackBuilderProgressHandler OnPackBuilderProgress { get; set; } } diff --git a/LibGit2Sharp/RemoteCallbacks.cs b/LibGit2Sharp/RemoteCallbacks.cs index 5815ed020..962a5d3ae 100644 --- a/LibGit2Sharp/RemoteCallbacks.cs +++ b/LibGit2Sharp/RemoteCallbacks.cs @@ -15,13 +15,11 @@ internal class RemoteCallbacks internal RemoteCallbacks( ProgressHandler onProgress = null, TransferProgressHandler onDownloadProgress = null, - CompletionHandler onCompletion = null, UpdateTipsHandler onUpdateTips = null, Credentials credentials = null) { Progress = onProgress; DownloadTransferProgress = onDownloadProgress; - Completion = onCompletion; UpdateTips = onUpdateTips; Credentials = credentials; } @@ -38,11 +36,6 @@ internal RemoteCallbacks( /// private readonly UpdateTipsHandler UpdateTips; - /// - /// Completion callback. Corresponds to libgit2 Completion callback. - /// - private readonly CompletionHandler Completion; - /// /// Managed delegate to be called in response to a git_transfer_progress_callback callback from libgit2. /// This will in turn call the user provided delegate. @@ -70,11 +63,6 @@ internal GitRemoteCallbacks GenerateCallbacks() callbacks.update_tips = GitUpdateTipsHandler; } - if (Completion != null) - { - callbacks.completion = GitCompletionHandler; - } - if (Credentials != null) { callbacks.acquire_credentials = GitCredentialHandler; @@ -122,36 +110,15 @@ private void GitProgressHandler(IntPtr str, int len, IntPtr data) private int GitUpdateTipsHandler(IntPtr str, ref GitOid oldId, ref GitOid newId, IntPtr data) { UpdateTipsHandler onUpdateTips = UpdateTips; - int result = 0; + bool shouldContinue = true; if (onUpdateTips != null) { string refName = LaxUtf8Marshaler.FromNative(str); - result = onUpdateTips(refName, oldId, newId); - } - - return result; - } - - /// - /// Handler for libgit2 completion callback. Converts values - /// received from libgit2 callback to more suitable types - /// and calls delegate provided by LibGit2Sharp consumer. - /// - /// Which operation completed. - /// IntPtr to optional payload passed back to the callback. - /// 0 on success; a negative value to abort the process. - private int GitCompletionHandler(RemoteCompletionType remoteCompletionType, IntPtr data) - { - CompletionHandler completion = Completion; - int result = 0; - - if (completion != null) - { - result = completion(remoteCompletionType); + shouldContinue = onUpdateTips(refName, oldId, newId); } - return result; + return Proxy.ConvertResultToCancelFlag(shouldContinue); } /// @@ -162,14 +129,14 @@ private int GitCompletionHandler(RemoteCompletionType remoteCompletionType, IntP /// the result of the wrapped private int GitDownloadTransferProgressHandler(ref GitTransferProgress progress, IntPtr payload) { - int result = 0; + bool shouldContinue = true; if (DownloadTransferProgress != null) { - result = DownloadTransferProgress(new TransferProgress(progress)); + shouldContinue = DownloadTransferProgress(new TransferProgress(progress)); } - return result; + return Proxy.ConvertResultToCancelFlag(shouldContinue); } private int GitCredentialHandler(out IntPtr cred, IntPtr url, IntPtr username_from_url, uint types, IntPtr payload) diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index 93b726f88..e99145627 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -560,7 +560,7 @@ public static string Clone(string sourceUrl, string workdirPath, { CheckoutCallbacks checkoutCallbacks = CheckoutCallbacks.GenerateCheckoutCallbacks(onCheckoutProgress, null); - var callbacks = new RemoteCallbacks(null, onTransferProgress, null, null, credentials); + var callbacks = new RemoteCallbacks(null, onTransferProgress, null, credentials); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); var cloneOpts = new GitCloneOptions diff --git a/LibGit2Sharp/RepositoryExtensions.cs b/LibGit2Sharp/RepositoryExtensions.cs index f00e69719..30e8bb8f4 100644 --- a/LibGit2Sharp/RepositoryExtensions.cs +++ b/LibGit2Sharp/RepositoryExtensions.cs @@ -227,7 +227,6 @@ public static Commit Commit(this IRepository repository, string message, Signatu /// The name of the to fetch from. /// 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. /// Callback method that transfer progress will be reported through. /// Reports the client's state regarding the received and processed (bytes, objects) from the server. @@ -235,7 +234,6 @@ public static Commit Commit(this IRepository repository, string message, Signatu public static void Fetch(this IRepository repository, string remoteName, TagFetchMode tagFetchMode = TagFetchMode.Auto, ProgressHandler onProgress = null, - CompletionHandler onCompletion = null, UpdateTipsHandler onUpdateTips = null, TransferProgressHandler onTransferProgress = null, Credentials credentials = null) @@ -244,7 +242,7 @@ public static void Fetch(this IRepository repository, string remoteName, Ensure.ArgumentNotNullOrEmptyString(remoteName, "remoteName"); Remote remote = repository.Network.Remotes.RemoteForName(remoteName, true); - repository.Network.Fetch(remote, tagFetchMode, onProgress, onCompletion, onUpdateTips, + repository.Network.Fetch(remote, tagFetchMode, onProgress, onUpdateTips, onTransferProgress, credentials); }