/// <summary> /// Rename an existing local branch /// </summary> /// <param name="branch">The current local branch.</param> /// <param name="newName">The new name the existing branch should bear.</param> /// <param name="signature">Identity used for updating the reflog</param> /// <param name="logMessage">Message added to the reflog. If null, the default is "branch: renamed [old] to [new]".</param> /// <param name="allowOverwrite">True to allow silent overwriting a potentially existing branch, false otherwise.</param> /// <returns>A new <see cref="Branch"/>.</returns> public virtual Branch Rename(Branch branch, string newName, Signature signature, string logMessage = null, bool allowOverwrite = false) { Ensure.ArgumentNotNull(branch, "branch"); Ensure.ArgumentNotNullOrEmptyString(newName, "newName"); if (branch.IsRemote) { throw new LibGit2SharpException( string.Format(CultureInfo.InvariantCulture, "Cannot rename branch '{0}'. It's a remote tracking branch.", branch.Name)); } if (logMessage == null) { logMessage = string.Format(CultureInfo.InvariantCulture, "branch: renamed {0} to {1}", branch.CanonicalName, Reference.LocalBranchPrefix + newName); } using (ReferenceSafeHandle referencePtr = repo.Refs.RetrieveReferencePtr(Reference.LocalBranchPrefix + branch.Name)) { using (Proxy.git_branch_move(referencePtr, newName, allowOverwrite, signature.OrDefault(repo.Config), logMessage)) { } } var newBranch = this[newName]; return(newBranch); }
/// <summary> /// Fetch from the <see cref="Remote"/>. /// </summary> /// <param name="remote">The remote to fetch</param> /// <param name="options"><see cref="FetchOptions"/> controlling fetch 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 Fetch(Remote remote, FetchOptions options = null, Signature signature = null, string logMessage = null) { Ensure.ArgumentNotNull(remote, "remote"); using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, remote.Name, true)) { DoFetch(remoteHandle, options, signature.OrDefault(repository.Config), logMessage); } }
/// <summary> /// Fetch from the <see cref="Remote"/>, using custom refspecs. /// </summary> /// <param name="remote">The remote to fetch</param> /// <param name="refspecs">Refspecs to use, replacing the remote's fetch refspecs</param> /// <param name="options"><see cref="FetchOptions"/> controlling fetch 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 Fetch(Remote remote, IEnumerable <string> refspecs, FetchOptions options = null, Signature signature = null, string logMessage = null) { Ensure.ArgumentNotNull(remote, "remote"); Ensure.ArgumentNotNull(refspecs, "refspecs"); using (RemoteSafeHandle remoteHandle = Proxy.git_remote_lookup(repository.Handle, remote.Name, true)) { Proxy.git_remote_set_fetch_refspecs(remoteHandle, refspecs); DoFetch(remoteHandle, options, signature.OrDefault(repository.Config), logMessage); } }
/// <summary> /// Fetch from a url with a set of fetch refspecs /// </summary> /// <param name="url">The url to fetch from</param> /// <param name="refspecs">The list of resfpecs to use</param> /// <param name="options"><see cref="FetchOptions"/> controlling fetch 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 Fetch( string url, IEnumerable <string> refspecs, FetchOptions options = null, Signature signature = null, string logMessage = null) { Ensure.ArgumentNotNull(url, "url"); Ensure.ArgumentNotNull(refspecs, "refspecs"); using (RemoteSafeHandle remoteHandle = Proxy.git_remote_create_anonymous(repository.Handle, url, null)) { Proxy.git_remote_set_fetch_refspecs(remoteHandle, refspecs); DoFetch(remoteHandle, options, signature.OrDefault(repository.Config), logMessage); } }
/// <summary> /// Updates the target of a symbolic reference /// </summary> /// <param name="symbolicRef">The symbolic reference which target should be updated.</param> /// <param name="targetRef">The new target.</param> /// <param name="signature">The identity used for updating the reflog.</param> /// <param name="logMessage">The optional message to log in the <see cref="ReflogCollection"/> of the <paramref name="symbolicRef"/> reference.</param> /// <returns>A new <see cref="Reference"/>.</returns> public virtual Reference UpdateTarget(Reference symbolicRef, Reference targetRef, Signature signature, string logMessage) { Ensure.ArgumentNotNull(symbolicRef, "symbolicRef"); Ensure.ArgumentNotNull(targetRef, "targetRef"); signature = signature.OrDefault(repo.Config); if (symbolicRef.CanonicalName == "HEAD") { return(UpdateHeadTarget(targetRef, signature, logMessage)); } using (ReferenceSafeHandle referencePtr = RetrieveReferencePtr(symbolicRef.CanonicalName)) using (ReferenceSafeHandle handle = Proxy.git_reference_symbolic_set_target(referencePtr, targetRef.CanonicalName, signature, logMessage)) { return(Reference.BuildFromPtr <Reference>(handle, repo)); } }
/// <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> /// Updates the target of a reference /// </summary> /// <param name="refsColl">The <see cref="ReferenceCollection"/> being worked with.</param> /// <param name="name">The canonical name of the reference.</param> /// <param name="canonicalRefNameOrObjectish">The target which can be either the canonical name of a reference or a revparse spec.</param> /// <param name="signature">The identity used for updating the reflog</param> /// <param name="logMessage">The optional message to log in the <see cref="ReflogCollection"/> of the <paramref name="name"/> reference.</param> /// <returns>A new <see cref="Reference"/>.</returns> public static Reference UpdateTarget(this ReferenceCollection refsColl, string name, string canonicalRefNameOrObjectish, Signature signature, string logMessage) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); Ensure.ArgumentNotNullOrEmptyString(canonicalRefNameOrObjectish, "canonicalRefNameOrObjectish"); signature = signature.OrDefault(refsColl.repo.Config); if (name == "HEAD") { return(refsColl.UpdateHeadTarget(canonicalRefNameOrObjectish, signature, logMessage)); } Reference reference = refsColl[name]; var directReference = reference as DirectReference; if (directReference != null) { return(refsColl.UpdateTarget(directReference, canonicalRefNameOrObjectish, signature, logMessage)); } var symbolicReference = reference as SymbolicReference; if (symbolicReference != null) { Reference targetRef; RefState refState = TryResolveReference(out targetRef, refsColl, canonicalRefNameOrObjectish); if (refState == RefState.DoesNotLookValid) { throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The reference specified by {0} is a Symbolic reference, you must provide a reference canonical name as the target.", name), "canonicalRefNameOrObjectish"); } return(refsColl.UpdateTarget(symbolicReference, targetRef, signature, logMessage)); } throw new LibGit2SharpException(string.Format(CultureInfo.InvariantCulture, "Reference '{0}' has an unexpected type ('{1}').", name, reference.GetType())); }
/// <summary> /// Create a new local branch with the specified name /// </summary> /// <param name="name">The name of the branch.</param> /// <param name="commit">The target commit.</param> /// <param name="signature">Identity used for updating the reflog</param> /// <param name="logMessage">Message added to the reflog. If null, the default is "branch: Created from [sha]".</param> /// <param name="allowOverwrite">True to allow silent overwriting a potentially existing branch, false otherwise.</param> /// <returns>A new <see cref="Branch"/>.</returns> public virtual Branch Add(string name, Commit commit, Signature signature, string logMessage = null, bool allowOverwrite = false) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); Ensure.ArgumentNotNull(commit, "commit"); if (logMessage == null) { logMessage = "branch: Created from " + commit.Id; } using (Proxy.git_branch_create(repo.Handle, name, commit.Id, allowOverwrite, signature.OrDefault(repo.Config), logMessage)) {} var branch = this[ShortToLocalName(name)]; return(branch); }
/// <summary> /// Creates a direct reference with the specified name and target /// </summary> /// <param name="name">The canonical name of the reference to create.</param> /// <param name="targetId">Id of the target object.</param> /// <param name="signature">Identity used for updating the reflog.</param> /// <param name="logMessage">The optional message to log in the <see cref="ReflogCollection"/> when adding the <see cref="DirectReference"/></param> /// <param name="allowOverwrite">True to allow silent overwriting a potentially existing reference, false otherwise.</param> /// <returns>A new <see cref="Reference"/>.</returns> public virtual DirectReference Add(string name, ObjectId targetId, Signature signature, string logMessage, bool allowOverwrite = false) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); Ensure.ArgumentNotNull(targetId, "targetId"); using (ReferenceSafeHandle handle = Proxy.git_reference_create(repo.Handle, name, targetId, allowOverwrite, signature.OrDefault(repo.Config), logMessage)) { return((DirectReference)Reference.BuildFromPtr <Reference>(handle, repo)); } }
/// <summary> /// Rename an existing reference with a new name, and update the reflog /// </summary> /// <param name="reference">The reference to rename.</param> /// <param name="newName">The new canonical name.</param> /// <param name="signature">Identity used for updating the reflog.</param> /// <param name="logMessage">Message added to the reflog.</param> /// <param name="allowOverwrite">True to allow silent overwriting a potentially existing reference, false otherwise.</param> /// <returns>A new <see cref="Reference"/>.</returns> public virtual Reference Rename(Reference reference, string newName, Signature signature, string logMessage = null, bool allowOverwrite = false) { Ensure.ArgumentNotNull(reference, "reference"); Ensure.ArgumentNotNullOrEmptyString(newName, "newName"); if (logMessage == null) { logMessage = string.Format(CultureInfo.InvariantCulture, "{0}: renamed {1} to {2}", reference.IsLocalBranch() ? "branch" : "reference", reference.CanonicalName, newName); } using (ReferenceSafeHandle referencePtr = RetrieveReferencePtr(reference.CanonicalName)) using (ReferenceSafeHandle handle = Proxy.git_reference_rename(referencePtr, newName, allowOverwrite, signature.OrDefault(repo.Config), logMessage)) { return(Reference.BuildFromPtr <Reference>(handle, repo)); } }
/// <summary> /// Creates a symbolic reference with the specified name and target /// </summary> /// <param name="name">The canonical name of the reference to create.</param> /// <param name="targetRef">The target reference.</param> /// <param name="signature">Identity used for updating the reflog.</param> /// <param name="logMessage">The optional message to log in the <see cref="ReflogCollection"/> when adding the <see cref="SymbolicReference"/></param> /// <param name="allowOverwrite">True to allow silent overwriting a potentially existing reference, false otherwise.</param> /// <returns>A new <see cref="Reference"/>.</returns> public virtual SymbolicReference Add(string name, Reference targetRef, Signature signature, string logMessage, bool allowOverwrite = false) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); Ensure.ArgumentNotNull(targetRef, "targetRef"); using (ReferenceSafeHandle handle = Proxy.git_reference_symbolic_create(repo.Handle, name, targetRef.CanonicalName, allowOverwrite, signature.OrDefault(repo.Config), logMessage)) { return((SymbolicReference)Reference.BuildFromPtr <Reference>(handle, repo)); } }
/// <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> /// Creates a direct or symbolic reference with the specified name and target /// </summary> /// <param name="refsColl">The <see cref="ReferenceCollection"/> being worked with.</param> /// <param name="name">The name of the reference to create.</param> /// <param name="canonicalRefNameOrObjectish">The target which can be either the canonical name of a reference or a revparse spec.</param> /// <param name="signature">The identity used for updating the reflog</param> /// <param name="logMessage">The optional message to log in the <see cref="ReflogCollection"/> when adding the <see cref="Reference"/></param> /// <param name="allowOverwrite">True to allow silent overwriting a potentially existing reference, false otherwise.</param> /// <returns>A new <see cref="Reference"/>.</returns> public static Reference Add(this ReferenceCollection refsColl, string name, string canonicalRefNameOrObjectish, Signature signature, string logMessage, bool allowOverwrite = false) { Ensure.ArgumentNotNullOrEmptyString(name, "name"); Ensure.ArgumentNotNullOrEmptyString(canonicalRefNameOrObjectish, "canonicalRefNameOrObjectish"); Reference reference; RefState refState = TryResolveReference(out reference, refsColl, canonicalRefNameOrObjectish); var gitObject = refsColl.repo.Lookup(canonicalRefNameOrObjectish, GitObjectType.Any, LookUpOptions.None); if (refState == RefState.Exists) { return(refsColl.Add(name, reference, signature, logMessage, allowOverwrite)); } if (refState == RefState.DoesNotExistButLooksValid && gitObject == null) { using (ReferenceSafeHandle handle = Proxy.git_reference_symbolic_create(refsColl.repo.Handle, name, canonicalRefNameOrObjectish, allowOverwrite, signature.OrDefault(refsColl.repo.Config), logMessage)) { return(Reference.BuildFromPtr <Reference>(handle, refsColl.repo)); } } Ensure.GitObjectIsNotNull(gitObject, canonicalRefNameOrObjectish); if (logMessage == null) { logMessage = string.Format(CultureInfo.InvariantCulture, "{0}: Created from {1}", name.LooksLikeLocalBranch() ? "branch" : "reference", canonicalRefNameOrObjectish); } refsColl.EnsureHasLog(name); return(refsColl.Add(name, gitObject.Id, signature, logMessage, allowOverwrite)); }