/// <summary> /// Update specified submodule. /// <para> /// This will: /// 1) Optionally initialize the if it not already initialzed, /// 2) clone the sub repository if it has not already been cloned, and /// 3) checkout the commit ID for the submodule in the sub repository. /// </para> /// </summary> /// <param name="name">The name of the submodule to update.</param> /// <param name="options">Options controlling submodule udpate behavior and callbacks.</param> public virtual void Update(string name, SubmoduleUpdateOptions options) { options = options ?? new SubmoduleUpdateOptions(); using (var handle = Proxy.git_submodule_lookup(repo.Handle, name)) { if (handle == null) { throw new NotFoundException("Submodule lookup failed for '{0}'.", name); } using (GitCheckoutOptsWrapper checkoutOptionsWrapper = new GitCheckoutOptsWrapper(options)) { var gitCheckoutOptions = checkoutOptionsWrapper.Options; var remoteCallbacks = new RemoteCallbacks(options); var gitRemoteCallbacks = remoteCallbacks.GenerateCallbacks(); var gitSubmoduleUpdateOpts = new GitSubmoduleOptions { Version = 1, CheckoutOptions = gitCheckoutOptions, FetchOptions = new GitFetchOptions { RemoteCallbacks = gitRemoteCallbacks }, CloneCheckoutStrategy = CheckoutStrategy.GIT_CHECKOUT_SAFE }; Proxy.git_submodule_update(handle, options.Init, ref gitSubmoduleUpdateOpts); } } }
/// <summary> /// Push specified references to the <see cref="Remote"/>. /// </summary> /// <param name="remote">The <see cref="Remote"/> to push to.</param> /// <param name="pushRefSpecs">The pushRefSpecs to push.</param> /// <param name="pushOptions"><see cref="PushOptions"/> controlling push behavior</param> public virtual void Push(Remote remote, IEnumerable <string> pushRefSpecs, PushOptions pushOptions) { Ensure.ArgumentNotNull(remote, "remote"); Ensure.ArgumentNotNull(pushRefSpecs, "pushRefSpecs"); // Return early if there is nothing to push. if (!pushRefSpecs.Any()) { return; } if (pushOptions == null) { pushOptions = new PushOptions(); } // Load the remote. using (RemoteHandle remoteHandle = Proxy.git_remote_lookup(repository.Handle, remote.Name, true)) { var callbacks = new RemoteCallbacks(pushOptions); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); Proxy.git_remote_push(remoteHandle, pushRefSpecs, new GitPushOptions() { PackbuilderDegreeOfParallelism = pushOptions.PackbuilderDegreeOfParallelism, RemoteCallbacks = gitCallbacks, ProxyOptions = new GitProxyOptions { Version = 1 }, CustomHeaders = GitStrArrayManaged.BuildFrom(pushOptions.CustomHeaders), }); } }
static void DoFetch(RemoteSafeHandle remoteHandle, FetchOptions options, Signature signature, string logMessage) { if (options == null) { options = new FetchOptions(); } if (options.TagFetchMode.HasValue) { Proxy.git_remote_set_autotag(remoteHandle, options.TagFetchMode.Value); } var callbacks = new RemoteCallbacks(options); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); // It is OK to pass the reference to the GitCallbacks directly here because libgit2 makes a copy of // the data in the git_remote_callbacks structure. If, in the future, libgit2 changes its implementation // to store a reference to the git_remote_callbacks structure this would introduce a subtle bug // where the managed layer could move the git_remote_callbacks to a different location in memory, // but libgit2 would still reference the old address. // // Also, if GitRemoteCallbacks were a class instead of a struct, we would need to guard against // GC occuring in between setting the remote callbacks and actual usage in one of the functions afterwords. Proxy.git_remote_set_callbacks(remoteHandle, ref gitCallbacks); Proxy.git_remote_fetch(remoteHandle, signature, logMessage); }
private static void DoFetch(FetchOptions options, RemoteSafeHandle remoteHandle, string logMessage, IEnumerable <string> refspecs) { Debug.Assert(remoteHandle != null && !remoteHandle.IsClosed && !remoteHandle.IsInvalid); options = options ?? new FetchOptions(); var callbacks = new RemoteCallbacks(options); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); // It is OK to pass the reference to the GitCallbacks directly here because libgit2 makes a copy of // the data in the git_remote_callbacks structure. If, in the future, libgit2 changes its implementation // to store a reference to the git_remote_callbacks structure this would introduce a subtle bug // where the managed layer could move the git_remote_callbacks to a different location in memory, // but libgit2 would still reference the old address. // // Also, if GitRemoteCallbacks were a class instead of a struct, we would need to guard against // GC occuring in between setting the remote callbacks and actual usage in one of the functions afterwords. var fetchOptions = new GitFetchOptions { RemoteCallbacks = gitCallbacks, download_tags = Proxy.git_remote_autotag(remoteHandle), }; if (options.TagFetchMode.HasValue) { fetchOptions.download_tags = options.TagFetchMode.Value; } Proxy.git_remote_fetch(remoteHandle, refspecs, fetchOptions, logMessage); }
/// <summary> /// Fetch from the <see cref = "Remote" />. /// </summary> /// <param name="remote">The remote to fetch</param> /// <param name="tagFetchMode">Optional parameter indicating what tags to download.</param> /// <param name="onProgress">Progress callback. Corresponds to libgit2 progress callback.</param> /// <param name="onCompletion">Completion callback. Corresponds to libgit2 completion callback.</param> /// <param name="onUpdateTips">UpdateTips callback. Corresponds to libgit2 update_tips callback.</param> /// <param name="onTransferProgress">Callback method that transfer progress will be reported through. /// Reports the client's state regarding the received and processed (bytes, objects) from the server.</param> /// <param name="credentials">Credentials to use for username/password authentication.</param> public virtual void Fetch( Remote remote, TagFetchMode tagFetchMode = TagFetchMode.Auto, ProgressHandler onProgress = null, CompletionHandler onCompletion = null, UpdateTipsHandler onUpdateTips = null, TransferProgressHandler onTransferProgress = null, Credentials credentials = null) { Ensure.ArgumentNotNull(remote, "remote"); // We need to keep a reference to the git_cred_acquire_cb callback around // so it will not be garbage collected before we are done with it. // Note that we also have a GC.KeepAlive call at the end of the method. NativeMethods.git_cred_acquire_cb credentialCallback = null; using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, remote.Name, true)) { var callbacks = new RemoteCallbacks(onProgress, onCompletion, onUpdateTips); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); Proxy.git_remote_set_autotag(remoteHandle, tagFetchMode); if (credentials != null) { credentialCallback = (out IntPtr cred, IntPtr url, IntPtr username_from_url, uint types, IntPtr payload) => NativeMethods.git_cred_userpass_plaintext_new(out cred, credentials.Username, credentials.Password); Proxy.git_remote_set_cred_acquire_cb( remoteHandle, credentialCallback, IntPtr.Zero); } // It is OK to pass the reference to the GitCallbacks directly here because libgit2 makes a copy of // the data in the git_remote_callbacks structure. If, in the future, libgit2 changes its implementation // to store a reference to the git_remote_callbacks structure this would introduce a subtle bug // where the managed layer could move the git_remote_callbacks to a different location in memory, // but libgit2 would still reference the old address. // // Also, if GitRemoteCallbacks were a class instead of a struct, we would need to guard against // GC occuring in between setting the remote callbacks and actual usage in one of the functions afterwords. Proxy.git_remote_set_callbacks(remoteHandle, ref gitCallbacks); try { Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch); Proxy.git_remote_download(remoteHandle, onTransferProgress); Proxy.git_remote_update_tips(remoteHandle); } finally { Proxy.git_remote_disconnect(remoteHandle); } } // To be safe, make sure the credential callback is kept until // alive until at least this point. GC.KeepAlive(credentialCallback); }
/// <summary> /// Perform a fetch /// </summary> /// <param name="repository">The repository in which to fetch.</param> /// <param name="remote">The remote to fetch from. Either as a remote name or a URL</param> /// <param name="options">Fetch options.</param> /// <param name="logMessage">Log message for any ref updates.</param> /// <param name="refspecs">List of refspecs to apply as active.</param> public static void Fetch(Repository repository, string remote, IEnumerable <string> refspecs, FetchOptions options, string logMessage) { Ensure.ArgumentNotNull(remote, "remote"); options = options ?? new FetchOptions(); using (var remoteHandle = RemoteFromNameOrUrl(repository.Handle, remote)) using (var fetchOptionsWrapper = new GitFetchOptionsWrapper()) { var callbacks = new RemoteCallbacks(options); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); // It is OK to pass the reference to the GitCallbacks directly here because libgit2 makes a copy of // the data in the git_remote_callbacks structure. If, in the future, libgit2 changes its implementation // to store a reference to the git_remote_callbacks structure this would introduce a subtle bug // where the managed layer could move the git_remote_callbacks to a different location in memory, // but libgit2 would still reference the old address. // // Also, if GitRemoteCallbacks were a class instead of a struct, we would need to guard against // GC occuring in between setting the remote callbacks and actual usage in one of the functions afterwords. var fetchOptions = fetchOptionsWrapper.Options; fetchOptions.RemoteCallbacks = gitCallbacks; fetchOptions.download_tags = Proxy.git_remote_autotag(remoteHandle); if (options.TagFetchMode.HasValue) { fetchOptions.download_tags = options.TagFetchMode.Value; } if (options.Prune.HasValue) { fetchOptions.Prune = options.Prune.Value ? FetchPruneStrategy.Prune : FetchPruneStrategy.NoPrune; } else { fetchOptions.Prune = FetchPruneStrategy.FromConfigurationOrDefault; } if (options.CustomHeaders != null && options.CustomHeaders.Length > 0) { fetchOptions.CustomHeaders = GitStrArrayManaged.BuildFrom(options.CustomHeaders); } fetchOptions.ProxyOptions = new GitProxyOptions { Version = 1 }; Proxy.git_remote_fetch(remoteHandle, refspecs, fetchOptions, logMessage); } }
/// <summary> /// List references in a <see cref="Remote"/> repository. /// <para> /// When the remote tips are ahead of the local ones, the retrieved /// <see cref="DirectReference"/>s may point to non existing /// <see cref="GitObject"/>s in the local repository. In that /// case, <see cref="DirectReference.Target"/> will return <c>null</c>. /// </para> /// </summary> /// <param name="remote">The <see cref="Remote"/> to list from.</param> /// <param name="credentialsProvider">The optional <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 = null) { Ensure.ArgumentNotNull(remote, "remote"); using (RemoteSafeHandle remoteHandle = Proxy.git_remote_lookup(repository.Handle, remote.Name, true)) { if (credentialsProvider != null) { var callbacks = new RemoteCallbacks(credentialsProvider); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); Proxy.git_remote_set_callbacks(remoteHandle, ref gitCallbacks); } Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch); return(Proxy.git_remote_ls(repository, remoteHandle)); } }
/// <summary> /// List references in a <see cref="Remote"/> repository. /// <para> /// When the remote tips are ahead of the local ones, the retrieved /// <see cref="DirectReference"/>s may point to non existing /// <see cref="GitObject"/>s in the local repository. In that /// case, <see cref="DirectReference.Target"/> will return <c>null</c>. /// </para> /// </summary> /// <param name="remote">The <see cref="Remote"/> to list from.</param> /// <param name="credentialsProvider">The optional <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 = null) { Ensure.ArgumentNotNull(remote, "remote"); using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, remote.Name, true)) { if (credentialsProvider != null) { var callbacks = new RemoteCallbacks(null, null, null, credentialsProvider); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); Proxy.git_remote_set_callbacks(remoteHandle, ref gitCallbacks); } Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch); return Proxy.git_remote_ls(repository, remoteHandle); } }
private IEnumerable <Reference> ListReferencesInternal(string url, CredentialsHandler credentialsProvider) { using (RemoteSafeHandle remoteHandle = BuildRemoteSafeHandle(repository.Handle, url)) { GitRemoteCallbacks gitCallbacks = new GitRemoteCallbacks { version = 1 }; if (credentialsProvider != null) { var callbacks = new RemoteCallbacks(credentialsProvider); gitCallbacks = callbacks.GenerateCallbacks(); } Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch, ref gitCallbacks); return(Proxy.git_remote_ls(repository, remoteHandle)); } }
/// <summary> /// Push specified references to the <see cref="Remote"/>. /// </summary> /// <param name="remote">The <see cref="Remote"/> to push to.</param> /// <param name="pushRefSpecs">The pushRefSpecs to push.</param> /// <param name="pushOptions"><see cref="PushOptions"/> controlling push behavior</param> /// <param name="signature">Identity for use when updating the reflog.</param> /// <param name="logMessage">Message to use when updating the reflog.</param> public virtual void Push( Remote remote, IEnumerable <string> pushRefSpecs, PushOptions pushOptions = null, Signature signature = null, string logMessage = null) { Ensure.ArgumentNotNull(remote, "remote"); Ensure.ArgumentNotNull(pushRefSpecs, "pushRefSpecs"); // Return early if there is nothing to push. if (!pushRefSpecs.Any()) { return; } if (pushOptions == null) { pushOptions = new PushOptions(); } // Load the remote. using (RemoteSafeHandle remoteHandle = Proxy.git_remote_lookup(repository.Handle, remote.Name, true)) { var callbacks = new RemoteCallbacks(pushOptions); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); Proxy.git_remote_set_callbacks(remoteHandle, ref gitCallbacks); try { Proxy.git_remote_connect(remoteHandle, GitDirection.Push); Proxy.git_remote_push(remoteHandle, pushRefSpecs, new GitPushOptions() { PackbuilderDegreeOfParallelism = pushOptions.PackbuilderDegreeOfParallelism }, signature.OrDefault(repository.Config), logMessage); } finally { Proxy.git_remote_disconnect(remoteHandle); } } }
/// <summary> /// Perform a fetch /// </summary> /// <param name="repository">The repository in which to fetch.</param> /// <param name="remote">The remote to fetch from. Either as a remote name or a URL</param> /// <param name="options">Fetch options.</param> /// <param name="logMessage">Log message for any ref updates.</param> /// <param name="refspecs">List of refspecs to apply as active.</param> public static void Fetch(Repository repository, string remote, IEnumerable<string> refspecs, FetchOptions options, string logMessage) { Ensure.ArgumentNotNull(remote, "remote"); options = options ?? new FetchOptions(); using (var remoteHandle = RemoteFromNameOrUrl(repository.Handle, remote)) { var callbacks = new RemoteCallbacks(options); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); // It is OK to pass the reference to the GitCallbacks directly here because libgit2 makes a copy of // the data in the git_remote_callbacks structure. If, in the future, libgit2 changes its implementation // to store a reference to the git_remote_callbacks structure this would introduce a subtle bug // where the managed layer could move the git_remote_callbacks to a different location in memory, // but libgit2 would still reference the old address. // // Also, if GitRemoteCallbacks were a class instead of a struct, we would need to guard against // GC occuring in between setting the remote callbacks and actual usage in one of the functions afterwords. var fetchOptions = new GitFetchOptions { RemoteCallbacks = gitCallbacks, download_tags = Proxy.git_remote_autotag(remoteHandle), }; if (options.TagFetchMode.HasValue) { fetchOptions.download_tags = options.TagFetchMode.Value; } if (options.Prune.HasValue) { fetchOptions.Prune = options.Prune.Value ? FetchPruneStrategy.Prune : FetchPruneStrategy.NoPrune; } else { fetchOptions.Prune = FetchPruneStrategy.FromConfigurationOrDefault; } fetchOptions.ProxyOptions = new GitProxyOptions { Version = 1 }; Proxy.git_remote_fetch(remoteHandle, refspecs, fetchOptions, logMessage); } }
/// <summary> /// Clone with specified options. /// </summary> /// <param name="sourceUrl">URI for the remote repository</param> /// <param name="workdirPath">Local path to clone into</param> /// <param name="bare">True will result in a bare clone, false a full clone.</param> /// <param name="checkout">If true, the origin's HEAD will be checked out. This only applies /// to non-bare repositories.</param> /// <param name="onTransferProgress">Handler for network transfer and indexing progress information</param> /// <param name="onCheckoutProgress">Handler for checkout progress information</param> /// <param name="credentials">Credentials to use for user/pass authentication</param> /// <returns>The path to the created repository.</returns> public static string Clone(string sourceUrl, string workdirPath, bool bare = false, bool checkout = true, TransferProgressHandler onTransferProgress = null, CheckoutProgressHandler onCheckoutProgress = null, Credentials credentials = null) { CheckoutCallbacks checkoutCallbacks = CheckoutCallbacks.GenerateCheckoutCallbacks(onCheckoutProgress, null); var callbacks = new RemoteCallbacks(null, onTransferProgress, null, credentials); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); var cloneOpts = new GitCloneOptions { Bare = bare ? 1 : 0, CheckoutOpts = { version = 1, progress_cb = checkoutCallbacks.CheckoutProgressCallback, checkout_strategy = checkout ? CheckoutStrategy.GIT_CHECKOUT_SAFE_CREATE : CheckoutStrategy.GIT_CHECKOUT_NONE }, RemoteCallbacks = gitCallbacks, }; FilePath repoPath; using (RepositorySafeHandle repo = Proxy.git_clone(sourceUrl, workdirPath, cloneOpts)) { repoPath = Proxy.git_repository_path(repo); } return(repoPath.Native); }
/// <summary> /// Push specified references to the <see cref="Remote"/>. /// </summary> /// <param name="remote">The <see cref="Remote"/> to push to.</param> /// <param name="pushRefSpecs">The pushRefSpecs to push.</param> /// <param name="pushOptions"><see cref="PushOptions"/> controlling push behavior</param> /// <param name="signature">Identity for use when updating the reflog.</param> /// <param name="logMessage">Message to use when updating the reflog.</param> public virtual void Push( Remote remote, IEnumerable<string> pushRefSpecs, PushOptions pushOptions = null, Signature signature = null, string logMessage = null) { Ensure.ArgumentNotNull(remote, "remote"); Ensure.ArgumentNotNull(pushRefSpecs, "pushRefSpecs"); // The following local variables are protected from garbage collection // by a GC.KeepAlive call at the end of the method. Otherwise, // random crashes during push progress reporting could occur. PushTransferCallbacks pushTransferCallbacks; PackbuilderCallbacks packBuilderCallbacks; NativeMethods.git_push_transfer_progress pushProgress; NativeMethods.git_packbuilder_progress packBuilderProgress; // Return early if there is nothing to push. if (!pushRefSpecs.Any()) { return; } if (pushOptions == null) { pushOptions = new PushOptions(); } PushCallbacks pushStatusUpdates = new PushCallbacks(pushOptions.OnPushStatusError); // Load the remote. using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, remote.Name, true)) { var callbacks = new RemoteCallbacks(null, null, null, pushOptions.Credentials); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); Proxy.git_remote_set_callbacks(remoteHandle, ref gitCallbacks); try { Proxy.git_remote_connect(remoteHandle, GitDirection.Push); // Perform the actual push. using (PushSafeHandle pushHandle = Proxy.git_push_new(remoteHandle)) { pushTransferCallbacks = new PushTransferCallbacks(pushOptions.OnPushTransferProgress); packBuilderCallbacks = new PackbuilderCallbacks(pushOptions.OnPackBuilderProgress); pushProgress = pushTransferCallbacks.GenerateCallback(); packBuilderProgress = packBuilderCallbacks.GenerateCallback(); Proxy.git_push_set_callbacks(pushHandle, pushProgress, packBuilderProgress); // Set push options. Proxy.git_push_set_options(pushHandle, new GitPushOptions() { PackbuilderDegreeOfParallelism = pushOptions.PackbuilderDegreeOfParallelism }); // Add refspecs. foreach (string pushRefSpec in pushRefSpecs) { Proxy.git_push_add_refspec(pushHandle, pushRefSpec); } Proxy.git_push_finish(pushHandle); if (!Proxy.git_push_unpack_ok(pushHandle)) { throw new LibGit2SharpException("Push failed - remote did not successfully unpack."); } Proxy.git_push_status_foreach(pushHandle, pushStatusUpdates.Callback); Proxy.git_push_update_tips(pushHandle, signature.OrDefault(repository.Config), logMessage); } } finally { Proxy.git_remote_disconnect(remoteHandle); } } GC.KeepAlive(pushProgress); GC.KeepAlive(packBuilderProgress); GC.KeepAlive(pushTransferCallbacks); GC.KeepAlive(packBuilderCallbacks); }
private IEnumerable<Reference> ListReferencesInternal(string url, CredentialsHandler credentialsProvider) { using (RemoteHandle remoteHandle = BuildRemoteHandle(repository.Handle, url)) { GitRemoteCallbacks gitCallbacks = new GitRemoteCallbacks { version = 1 }; GitProxyOptions proxyOptions = new GitProxyOptions { Version = 1 }; if (credentialsProvider != null) { var callbacks = new RemoteCallbacks(credentialsProvider); gitCallbacks = callbacks.GenerateCallbacks(); } Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch, ref gitCallbacks, ref proxyOptions); return Proxy.git_remote_ls(repository, remoteHandle); } }
/// <summary> /// Fetch from the <see cref="Remote"/>. /// </summary> /// <param name="remote">The remote to fetch</param> /// <param name="tagFetchMode">Optional parameter indicating what tags to download.</param> /// <param name="onProgress">Progress callback. Corresponds to libgit2 progress callback.</param> /// <param name="onUpdateTips">UpdateTips callback. Corresponds to libgit2 update_tips callback.</param> /// <param name="onTransferProgress">Callback method that transfer progress will be reported through. /// Reports the client's state regarding the received and processed (bytes, objects) from the server.</param> /// <param name="credentials">Credentials to use for username/password authentication.</param> public virtual void Fetch( Remote remote, TagFetchMode? tagFetchMode = null, ProgressHandler onProgress = null, UpdateTipsHandler onUpdateTips = null, TransferProgressHandler onTransferProgress = null, Credentials credentials = null) { Ensure.ArgumentNotNull(remote, "remote"); using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, remote.Name, true)) { var callbacks = new RemoteCallbacks(onProgress, onTransferProgress, onUpdateTips, credentials); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); if (tagFetchMode.HasValue) { Proxy.git_remote_set_autotag(remoteHandle, tagFetchMode.Value); } // It is OK to pass the reference to the GitCallbacks directly here because libgit2 makes a copy of // the data in the git_remote_callbacks structure. If, in the future, libgit2 changes its implementation // to store a reference to the git_remote_callbacks structure this would introduce a subtle bug // where the managed layer could move the git_remote_callbacks to a different location in memory, // but libgit2 would still reference the old address. // // Also, if GitRemoteCallbacks were a class instead of a struct, we would need to guard against // GC occuring in between setting the remote callbacks and actual usage in one of the functions afterwords. Proxy.git_remote_set_callbacks(remoteHandle, ref gitCallbacks); try { Proxy.git_remote_connect(remoteHandle, GitDirection.Fetch); Proxy.git_remote_download(remoteHandle); Proxy.git_remote_update_tips(remoteHandle); } finally { Proxy.git_remote_disconnect(remoteHandle); } } }
/// <summary> /// Push specified references to the <see cref="Remote"/>. /// </summary> /// <param name="remote">The <see cref="Remote"/> to push to.</param> /// <param name="pushRefSpecs">The pushRefSpecs to push.</param> /// <param name="pushOptions"><see cref="PushOptions"/> controlling push behavior</param> /// <param name="signature">Identity for use when updating the reflog.</param> /// <param name="logMessage">Message to use when updating the reflog.</param> public virtual void Push( Remote remote, IEnumerable<string> pushRefSpecs, PushOptions pushOptions = null, Signature signature = null, string logMessage = null) { Ensure.ArgumentNotNull(remote, "remote"); Ensure.ArgumentNotNull(pushRefSpecs, "pushRefSpecs"); // Return early if there is nothing to push. if (!pushRefSpecs.Any()) { return; } if (pushOptions == null) { pushOptions = new PushOptions(); } // Load the remote. using (RemoteSafeHandle remoteHandle = Proxy.git_remote_lookup(repository.Handle, remote.Name, true)) { var callbacks = new RemoteCallbacks(pushOptions); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); Proxy.git_remote_set_callbacks(remoteHandle, ref gitCallbacks); try { Proxy.git_remote_connect(remoteHandle, GitDirection.Push); Proxy.git_remote_push(remoteHandle, pushRefSpecs, new GitPushOptions() { PackbuilderDegreeOfParallelism = pushOptions.PackbuilderDegreeOfParallelism }, signature.OrDefault(repository.Config), logMessage); } finally { Proxy.git_remote_disconnect(remoteHandle); } } }
/// <summary> /// Push specified references to the <see cref="Remote"/>. /// </summary> /// <param name="remote">The <see cref="Remote"/> to push to.</param> /// <param name="pushRefSpecs">The pushRefSpecs to push.</param> /// <param name="pushOptions"><see cref="PushOptions"/> controlling push behavior</param> /// <param name="signature">Identity for use when updating the reflog.</param> /// <param name="logMessage">Message to use when updating the reflog.</param> public virtual void Push( Remote remote, IEnumerable <string> pushRefSpecs, PushOptions pushOptions = null, Signature signature = null, string logMessage = null) { Ensure.ArgumentNotNull(remote, "remote"); Ensure.ArgumentNotNull(pushRefSpecs, "pushRefSpecs"); // The following local variables are protected from garbage collection // by a GC.KeepAlive call at the end of the method. Otherwise, // random crashes during push progress reporting could occur. PushTransferCallbacks pushTransferCallbacks; PackbuilderCallbacks packBuilderCallbacks; NativeMethods.git_push_transfer_progress pushProgress; NativeMethods.git_packbuilder_progress packBuilderProgress; // Return early if there is nothing to push. if (!pushRefSpecs.Any()) { return; } if (pushOptions == null) { pushOptions = new PushOptions(); } PushCallbacks pushStatusUpdates = new PushCallbacks(pushOptions.OnPushStatusError); // Load the remote. using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, remote.Name, true)) { var callbacks = new RemoteCallbacks(null, null, null, pushOptions.Credentials); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); Proxy.git_remote_set_callbacks(remoteHandle, ref gitCallbacks); try { Proxy.git_remote_connect(remoteHandle, GitDirection.Push); // Perform the actual push. using (PushSafeHandle pushHandle = Proxy.git_push_new(remoteHandle)) { pushTransferCallbacks = new PushTransferCallbacks(pushOptions.OnPushTransferProgress); packBuilderCallbacks = new PackbuilderCallbacks(pushOptions.OnPackBuilderProgress); pushProgress = pushTransferCallbacks.GenerateCallback(); packBuilderProgress = packBuilderCallbacks.GenerateCallback(); Proxy.git_push_set_callbacks(pushHandle, pushProgress, packBuilderProgress); // Set push options. Proxy.git_push_set_options(pushHandle, new GitPushOptions() { PackbuilderDegreeOfParallelism = pushOptions.PackbuilderDegreeOfParallelism }); // Add refspecs. foreach (string pushRefSpec in pushRefSpecs) { Proxy.git_push_add_refspec(pushHandle, pushRefSpec); } Proxy.git_push_finish(pushHandle); if (!Proxy.git_push_unpack_ok(pushHandle)) { throw new LibGit2SharpException("Push failed - remote did not successfully unpack."); } Proxy.git_push_status_foreach(pushHandle, pushStatusUpdates.Callback); Proxy.git_push_update_tips(pushHandle, signature.OrDefault(repository.Config), logMessage); } } finally { Proxy.git_remote_disconnect(remoteHandle); } } GC.KeepAlive(pushProgress); GC.KeepAlive(packBuilderProgress); GC.KeepAlive(pushTransferCallbacks); GC.KeepAlive(packBuilderCallbacks); }
/// <summary> /// Push specified references to the <see cref="Remote"/>. /// </summary> /// <param name="remote">The <see cref="Remote"/> to push to.</param> /// <param name="pushRefSpecs">The pushRefSpecs to push.</param> /// <param name="pushOptions"><see cref="PushOptions"/> controlling push behavior</param> public virtual void Push( Remote remote, IEnumerable<string> pushRefSpecs, PushOptions pushOptions = null) { Ensure.ArgumentNotNull(remote, "remote"); Ensure.ArgumentNotNull(pushRefSpecs, "pushRefSpecs"); // Return early if there is nothing to push. if (!pushRefSpecs.Any()) { return; } if (pushOptions == null) { pushOptions = new PushOptions(); } PushCallbacks pushStatusUpdates = new PushCallbacks(pushOptions.OnPushStatusError); // Load the remote. using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, remote.Name, true)) { var callbacks = new RemoteCallbacks(null, null, null, pushOptions.Credentials); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); Proxy.git_remote_set_callbacks(remoteHandle, ref gitCallbacks); try { Proxy.git_remote_connect(remoteHandle, GitDirection.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() { PackbuilderDegreeOfParallelism = pushOptions.PackbuilderDegreeOfParallelism }); // Add refspecs. foreach (string pushRefSpec in pushRefSpecs) { Proxy.git_push_add_refspec(pushHandle, pushRefSpec); } Proxy.git_push_finish(pushHandle); if (!Proxy.git_push_unpack_ok(pushHandle)) { throw new LibGit2SharpException("Push failed - remote did not successfully unpack."); } Proxy.git_push_status_foreach(pushHandle, pushStatusUpdates.Callback); Proxy.git_push_update_tips(pushHandle); } } finally { Proxy.git_remote_disconnect(remoteHandle); } } }
/// <summary> /// Push specified references to the <see cref="Remote"/>. /// </summary> /// <param name="remote">The <see cref="Remote"/> to push to.</param> /// <param name="pushRefSpecs">The pushRefSpecs to push.</param> /// <param name="pushOptions"><see cref="PushOptions"/> controlling push behavior</param> public virtual void Push(Remote remote, IEnumerable<string> pushRefSpecs, PushOptions pushOptions) { Ensure.ArgumentNotNull(remote, "remote"); Ensure.ArgumentNotNull(pushRefSpecs, "pushRefSpecs"); // Return early if there is nothing to push. if (!pushRefSpecs.Any()) { return; } if (pushOptions == null) { pushOptions = new PushOptions(); } // Load the remote. using (RemoteHandle remoteHandle = Proxy.git_remote_lookup(repository.Handle, remote.Name, true)) { var callbacks = new RemoteCallbacks(pushOptions); GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks(); Proxy.git_remote_push(remoteHandle, pushRefSpecs, new GitPushOptions() { PackbuilderDegreeOfParallelism = pushOptions.PackbuilderDegreeOfParallelism, RemoteCallbacks = gitCallbacks, ProxyOptions = new GitProxyOptions { Version = 1 }, }); } }