/// <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);
        }
        private Reference UpdateTarget <T>(Reference reference, T target, Func <ReferenceSafeHandle, T, ReferenceSafeHandle> setter)
        {
            if (reference.CanonicalName == "HEAD")
            {
                if (target is ObjectId)
                {
                    return(Add("HEAD", target as ObjectId, true));
                }

                if (target is DirectReference)
                {
                    return(Add("HEAD", target as DirectReference, true));
                }

                if (target is SymbolicReference)
                {
                    return(Add("HEAD", target as SymbolicReference, true));
                }

                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture,
                                                          "'{0}' is not a valid target type.", typeof(T)));
            }

            using (ReferenceSafeHandle referencePtr = RetrieveReferencePtr(reference.CanonicalName))
            {
                using (ReferenceSafeHandle ref_out = setter(referencePtr, target))
                {
                    return(Reference.BuildFromPtr <Reference>(ref_out, repo));
                }
            }
        }
Example #3
0
        /// <summary>
        /// Creates a direct or symbolic reference with the specified name and target
        /// </summary>
        /// <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="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 virtual Reference Add(string name, string canonicalRefNameOrObjectish, string logMessage, bool allowOverwrite)
        {
            Ensure.ArgumentNotNullOrEmptyString(name, "name");
            Ensure.ArgumentNotNullOrEmptyString(canonicalRefNameOrObjectish, "canonicalRefNameOrObjectish");

            Reference reference;
            RefState  refState = TryResolveReference(out reference, this, canonicalRefNameOrObjectish);

            var gitObject = repo.Lookup(canonicalRefNameOrObjectish, GitObjectType.Any, LookUpOptions.None);

            if (refState == RefState.Exists)
            {
                return(Add(name, reference, logMessage, allowOverwrite));
            }

            if (refState == RefState.DoesNotExistButLooksValid && gitObject == null)
            {
                using (ReferenceSafeHandle handle = Proxy.git_reference_symbolic_create(repo.Handle, name, canonicalRefNameOrObjectish, allowOverwrite,
                                                                                        logMessage))
                {
                    return(Reference.BuildFromPtr <Reference>(handle, repo));
                }
            }

            Ensure.GitObjectIsNotNull(gitObject, canonicalRefNameOrObjectish);

            if (logMessage == null)
            {
                logMessage = string.Format(CultureInfo.InvariantCulture, "{0}: Created from {1}",
                                           name.LooksLikeLocalBranch() ? "branch" : "reference", canonicalRefNameOrObjectish);
            }

            EnsureHasLog(name);
            return(Add(name, gitObject.Id, logMessage, allowOverwrite));
        }
        /// <summary>
        /// Creates a direct or symbolic reference with the specified name and target
        /// </summary>
        /// <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="allowOverwrite">True to allow silent overwriting a potentially existing reference, false otherwise.</param>
        /// <param name="refsColl">The <see cref="ReferenceCollection"/> being worked with.</param>
        /// <param name="logMessage">The optional message to log in the <see cref="ReflogCollection"/> when adding the <see cref="Reference"/></param>
        /// <returns>A new <see cref="Reference"/>.</returns>
        public static Reference Add(this ReferenceCollection refsColl, string name, string canonicalRefNameOrObjectish, bool allowOverwrite = false, string logMessage = null)
        {
            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, allowOverwrite, logMessage));
            }

            if (refState == RefState.DoesNotExistButLooksValid && gitObject == null)
            {
                using (ReferenceSafeHandle handle = Proxy.git_reference_symbolic_create(refsColl.repo.Handle, name, canonicalRefNameOrObjectish, allowOverwrite))
                {
                    return(Reference.BuildFromPtr <Reference>(handle, refsColl.repo));
                }
            }

            Ensure.GitObjectIsNotNull(gitObject, canonicalRefNameOrObjectish);

            return(refsColl.Add(name, gitObject.Id, allowOverwrite, logMessage));
        }
Example #5
0
        internal static T BuildFromPtr <T>(ReferenceSafeHandle handle, Repository repo) where T : Reference
        {
            GitReferenceType type = Proxy.git_reference_type(handle);
            string           name = Proxy.git_reference_name(handle);

            Reference reference;

            switch (type)
            {
            case GitReferenceType.Symbolic:
                string targetIdentifier = Proxy.git_reference_symbolic_target(handle);

                var targetRef = repo.Refs[targetIdentifier];
                reference = new SymbolicReference(repo, name, targetIdentifier, targetRef);
                break;

            case GitReferenceType.Oid:
                ObjectId targetOid = Proxy.git_reference_target(handle);

                reference = new DirectReference(name, repo, targetOid);
                break;

            default:
                throw new LibGit2SharpException(CultureInfo.InvariantCulture, "Unable to build a new reference from a type '{0}'.", type);
            }

            return(reference as T);
        }
Example #6
0
 private Reference UpdateSymbolicRefenceTarget(Reference symbolicRef, Reference targetRef, string logMessage)
 {
     using (ReferenceSafeHandle referencePtr = RetrieveReferencePtr(symbolicRef.CanonicalName))
         using (ReferenceSafeHandle handle = Proxy.git_reference_symbolic_set_target(referencePtr, targetRef.CanonicalName, logMessage))
         {
             return(Reference.BuildFromPtr <Reference>(handle, repo));
         }
 }
Example #7
0
 private Reference UpdateDirectReferenceTarget(Reference directRef, ObjectId targetId, string logMessage)
 {
     using (ReferenceSafeHandle referencePtr = RetrieveReferencePtr(directRef.CanonicalName))
         using (ReferenceSafeHandle handle = Proxy.git_reference_set_target(referencePtr, targetId, logMessage))
         {
             return(Reference.BuildFromPtr <Reference>(handle, repo));
         }
 }
Example #8
0
        internal T Resolve <T>(string name) where T : Reference
        {
            Ensure.ArgumentNotNullOrEmptyString(name, "name");

            using (ReferenceSafeHandle referencePtr = RetrieveReferencePtr(name, false))
            {
                return(referencePtr == null ? null : Reference.BuildFromPtr <T>(referencePtr, repo));
            }
        }
Example #9
0
 /// <summary>
 ///   Add a new <see cref="ReflogEntry"/> to the current <see cref="ReflogCollection"/>. It will be created as first item of the collection
 ///   The native reflog object will be saved right after inserting the entry.
 /// </summary>
 /// <param name="target">the <see cref="ObjectId"/> of the new target the <see cref="Reference"/> will point out to.</param>
 /// <param name="reflogMessage">the message associated with the new <see cref="ReflogEntry"/>.</param>
 /// <param name="committer"><see cref="Signature"/> of the comitter.</param>
 internal virtual void Append(ObjectId target, string reflogMessage, Signature committer)
 {
     using (ReferenceSafeHandle reference = Proxy.git_reference_lookup(repo.Handle, canonicalName, true))
         using (ReflogSafeHandle reflog = Proxy.git_reflog_read(reference))
         {
             string prettifiedMessage = Proxy.git_message_prettify(reflogMessage);
             Proxy.git_reflog_append(reflog, target, committer, prettifiedMessage);
         }
 }
        /// <summary>
        /// Remove a reference from the repository
        /// </summary>
        /// <param name="reference">The reference to delete.</param>
        public virtual void Remove(Reference reference)
        {
            Ensure.ArgumentNotNull(reference, "reference");

            using (ReferenceSafeHandle handle = RetrieveReferencePtr(reference.CanonicalName))
            {
                Proxy.git_reference_delete(handle);
            }
        }
Example #11
0
        /// <summary>
        /// Start a rebase operation.
        /// </summary>
        /// <param name="branch">The branch to rebase.</param>
        /// <param name="upstream">The starting commit to rebase.</param>
        /// <param name="onto">The branch to rebase onto.</param>
        /// <param name="committer">The <see cref="Identity"/> of who added the change to the repository.</param>
        /// <param name="options">The <see cref="RebaseOptions"/> that specify the rebase behavior.</param>
        /// <returns>true if completed successfully, false if conflicts encountered.</returns>
        public virtual RebaseResult Start(Branch branch, Branch upstream, Branch onto, Identity committer, RebaseOptions options)
        {
            Ensure.ArgumentNotNull(upstream, "upstream");

            options = options ?? new RebaseOptions();

            EnsureNonBareRepo();

            if (this.repository.Info.CurrentOperation != CurrentOperation.None)
            {
                throw new LibGit2SharpException(string.Format(
                                                    "A {0} operation is already in progress.", this.repository.Info.CurrentOperation));
            }

            Func <Branch, ReferenceSafeHandle> RefHandleFromBranch = (Branch b) =>
            {
                return((b == null) ?
                       null :
                       this.repository.Refs.RetrieveReferencePtr(b.CanonicalName));
            };

            Func <ReferenceSafeHandle, GitAnnotatedCommitHandle> AnnotatedCommitHandleFromRefHandle =
                (ReferenceSafeHandle refHandle) =>
            {
                return((refHandle == null) ?
                       new GitAnnotatedCommitHandle() :
                       Proxy.git_annotated_commit_from_ref(this.repository.Handle, refHandle));
            };

            using (GitCheckoutOptsWrapper checkoutOptionsWrapper = new GitCheckoutOptsWrapper(options))
            {
                GitRebaseOptions gitRebaseOptions = new GitRebaseOptions()
                {
                    version          = 1,
                    checkout_options = checkoutOptionsWrapper.Options,
                };

                using (ReferenceSafeHandle branchRefPtr = RefHandleFromBranch(branch))
                    using (ReferenceSafeHandle upstreamRefPtr = RefHandleFromBranch(upstream))
                        using (ReferenceSafeHandle ontoRefPtr = RefHandleFromBranch(onto))
                            using (GitAnnotatedCommitHandle annotatedBranchCommitHandle = AnnotatedCommitHandleFromRefHandle(branchRefPtr))
                                using (GitAnnotatedCommitHandle upstreamRefAnnotatedCommitHandle = AnnotatedCommitHandleFromRefHandle(upstreamRefPtr))
                                    using (GitAnnotatedCommitHandle ontoRefAnnotatedCommitHandle = AnnotatedCommitHandleFromRefHandle(ontoRefPtr))
                                        using (RebaseSafeHandle rebaseOperationHandle = Proxy.git_rebase_init(this.repository.Handle,
                                                                                                              annotatedBranchCommitHandle,
                                                                                                              upstreamRefAnnotatedCommitHandle,
                                                                                                              ontoRefAnnotatedCommitHandle,
                                                                                                              gitRebaseOptions))
                                        {
                                            RebaseResult rebaseResult = RebaseOperationImpl.Run(rebaseOperationHandle,
                                                                                                this.repository,
                                                                                                committer,
                                                                                                options);
                                            return(rebaseResult);
                                        }
            }
        }
Example #12
0
        /// <summary>
        ///   Deletes the specified branch.
        /// </summary>
        /// <param name = "branch">The branch to delete.</param>
        public virtual void Remove(Branch branch)
        {
            Ensure.ArgumentNotNull(branch, "branch");

            using (ReferenceSafeHandle referencePtr = repo.Refs.RetrieveReferencePtr(branch.CanonicalName))
            {
                Proxy.git_branch_delete(referencePtr);
            }
        }
Example #13
0
        /// <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="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, string logMessage, bool allowOverwrite)
        {
            Ensure.ArgumentNotNullOrEmptyString(name, "name");
            Ensure.ArgumentNotNull(targetId, "targetId");

            using (ReferenceSafeHandle handle = Proxy.git_reference_create(repo.Handle, name, targetId, allowOverwrite, logMessage))
            {
                return((DirectReference)Reference.BuildFromPtr <Reference>(handle, repo));
            }
        }
Example #14
0
        /// <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 = "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, bool allowOverwrite = false)
        {
            Ensure.ArgumentNotNullOrEmptyString(name, "name");
            Ensure.ArgumentNotNull(targetRef, "targetRef");

            using (ReferenceSafeHandle handle = Proxy.git_reference_create_symbolic(repo.Handle, name, targetRef.CanonicalName, allowOverwrite))
            {
                return((SymbolicReference)Reference.BuildFromPtr <Reference>(handle, repo));
            }
        }
        /// <summary>
        /// Rename an existing reference with a new name
        /// </summary>
        /// <param name="reference">The reference to rename.</param>
        /// <param name="newName">The new canonical name.</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 Move(Reference reference, string newName, bool allowOverwrite = false)
        {
            Ensure.ArgumentNotNull(reference, "reference");
            Ensure.ArgumentNotNullOrEmptyString(newName, "newName");

            using (ReferenceSafeHandle handle = RetrieveReferencePtr(reference.CanonicalName))
            {
                using (ReferenceSafeHandle handle_out = Proxy.git_reference_rename(handle, newName, allowOverwrite))
                {
                    return(Reference.BuildFromPtr <Reference>(handle_out, repo));
                }
            }
        }
        /// <summary>
        ///   Rename an existing reference with a new name
        /// </summary>
        /// <param name = "currentName">The canonical name of the reference to rename.</param>
        /// <param name = "newName">The new canonical name.</param>
        /// <param name = "allowOverwrite">True to allow silent overwriting a potentially existing reference, false otherwise.</param>
        /// <returns></returns>
        public Reference Move(string currentName, string newName, bool allowOverwrite = false)
        {
            Ensure.ArgumentNotNullOrEmptyString(currentName, "currentName");
            Ensure.ArgumentNotNullOrEmptyString(newName, "newName");

            using (ReferenceSafeHandle handle = RetrieveReferencePtr(currentName))
            {
                int res = NativeMethods.git_reference_rename(handle, newName, allowOverwrite);
                Ensure.Success(res);

                return(Reference.BuildFromPtr <Reference>(handle, repo));
            }
        }
Example #17
0
        private static ReferenceSafeHandle PeelToDirectReference(ReferenceSafeHandle handle)
        {
            ReferenceSafeHandle resolvedHandle;
            int res = NativeMethods.git_reference_resolve(out resolvedHandle, handle);

            if (res == (int)GitErrorCode.GIT_ENOTFOUND)
            {
                return(null);
            }

            Ensure.Success(res);

            return(resolvedHandle);
        }
        /// <summary>
        ///   Delete a reference with the specified name
        /// </summary>
        /// <param name = "name">The name of the reference to delete.</param>
        public void Delete(string name)
        {
            Ensure.ArgumentNotNullOrEmptyString(name, "name");

            using (ReferenceSafeHandle handle = RetrieveReferencePtr(name))
            {
                int res = NativeMethods.git_reference_delete(handle);

                //TODO Make git_reference_delete() set the ref pointer to NULL and remove the following line
                handle.SetHandleAsInvalid();

                Ensure.Success(res);
            }
        }
        /// <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="allowOverwrite">True to allow silent overwriting a potentially existing reference, false otherwise.</param>
        /// <param name="logMessage">The optional message to log in the <see cref="ReflogCollection"/> when adding the <see cref="SymbolicReference"/></param>
        /// <returns>A new <see cref="Reference"/>.</returns>
        public virtual SymbolicReference Add(string name, Reference targetRef, bool allowOverwrite = false, string logMessage = null)
        {
            Ensure.ArgumentNotNullOrEmptyString(name, "name");
            Ensure.ArgumentNotNull(targetRef, "targetRef");

            using (ReferenceSafeHandle handle = Proxy.git_reference_symbolic_create(repo.Handle, name, targetRef.CanonicalName, allowOverwrite))
            {
                var newTarget = (SymbolicReference)Reference.BuildFromPtr <Reference>(handle, repo);

                LogReference(newTarget, targetRef, logMessage);

                return(newTarget);
            }
        }
        /// <summary>
        ///   Updates the target on a reference.
        /// </summary>
        /// <param name = "name">The name of the reference.</param>
        /// <param name = "target">The target which can be either a sha or the name of another reference.</param>
        public Reference UpdateTarget(string name, string target)
        {
            Ensure.ArgumentNotNullOrEmptyString(name, "name");
            Ensure.ArgumentNotNullOrEmptyString(target, "target");

            if (name == "HEAD")
            {
                return(Create("HEAD", target, true));
            }

            using (ReferenceSafeHandle referencePtr = RetrieveReferencePtr(name))
            {
                int res;

                ObjectId id;
                bool     isObjectIdentifier = ObjectId.TryParse(target, out id);

                GitReferenceType type = NativeMethods.git_reference_type(referencePtr);
                switch (type)
                {
                case GitReferenceType.Oid:
                    if (!isObjectIdentifier)
                    {
                        throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The reference specified by {0} is an Oid reference, you must provide a sha as the target.", name), "target");
                    }

                    GitOid oid = id.Oid;
                    res = NativeMethods.git_reference_set_oid(referencePtr, ref oid);
                    break;

                case GitReferenceType.Symbolic:
                    if (isObjectIdentifier)
                    {
                        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), "target");
                    }

                    res = NativeMethods.git_reference_set_target(referencePtr, target);
                    break;

                default:
                    throw new LibGit2Exception(string.Format(CultureInfo.InvariantCulture, "Reference '{0}' has an unexpected type ('{1}').", name, Enum.GetName(typeof(GitReferenceType), type)));
                }

                Ensure.Success(res);

                return(Reference.BuildFromPtr <Reference>(referencePtr, repo));
            }
        }
Example #21
0
        /// <summary>
        /// Add a new <see cref="ReflogEntry"/> to the current <see cref="ReflogCollection"/>. It will be created as first item of the collection
        /// The native reflog object will be saved right after inserting the entry.
        /// </summary>
        /// <param name="target">the <see cref="ObjectId"/> of the new target the <see cref="Reference"/> will point out to.</param>
        /// <param name="reflogMessage">the message associated with the new <see cref="ReflogEntry"/>.</param>
        /// <param name="committer"><see cref="Signature"/> of the comitter.</param>
        internal virtual void Append(ObjectId target, string reflogMessage, Signature committer)
        {
            var logAllRefUpdates = repo.Config.GetValueOrDefault <bool>("core.logAllRefUpdates", false);

            if (!logAllRefUpdates)
            {
                return;
            }

            using (ReferenceSafeHandle reference = Proxy.git_reference_lookup(repo.Handle, canonicalName, true))
                using (ReflogSafeHandle reflog = Proxy.git_reflog_read(reference))
                {
                    string prettifiedMessage = Proxy.git_message_prettify(reflogMessage);
                    Proxy.git_reflog_append(reflog, target, committer, prettifiedMessage);
                }
        }
Example #22
0
        /// <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));
                }
        }
Example #23
0
        internal static T BuildFromPtr <T>(ReferenceSafeHandle handle, Repository repo) where T : Reference
        {
            GitReferenceType type = NativeMethods.git_reference_type(handle);
            string           name = NativeMethods.git_reference_name(handle);

            Reference reference;

            switch (type)
            {
            case GitReferenceType.Symbolic:
                string targetIdentifier = NativeMethods.git_reference_target(handle);

                using (ReferenceSafeHandle resolvedHandle = PeelToDirectReference(handle))
                {
                    if (resolvedHandle == null)
                    {
                        reference = new SymbolicReference {
                            CanonicalName = name, Target = null, TargetIdentifier = targetIdentifier
                        };
                        break;
                    }

                    var targetRef = BuildFromPtr <DirectReference>(resolvedHandle, repo);
                    reference = new SymbolicReference {
                        CanonicalName = name, Target = targetRef, TargetIdentifier = targetIdentifier
                    };
                    break;
                }

            case GitReferenceType.Oid:
                ObjectId targetOid = NativeMethods.git_reference_oid(handle).MarshalAsObjectId();

                var targetBuilder = new Lazy <GitObject>(() => repo.Lookup(targetOid));
                reference = new DirectReference(targetBuilder)
                {
                    CanonicalName = name, TargetIdentifier = targetOid.Sha
                };
                break;

            default:
                throw new LibGit2Exception(String.Format(CultureInfo.InvariantCulture, "Unable to build a new reference from a type '{0}'.", Enum.GetName(typeof(GitReferenceType), type)));
            }

            return(reference as T);
        }
Example #24
0
        /// <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));
                }
        }
Example #25
0
        /// <summary>
        /// Returns an enumerator that iterates through the collection.
        /// <para>
        ///   The enumerator returns the <see cref="ReflogEntry"/> by descending order (last reflog entry is returned first).
        /// </para>
        /// </summary>
        /// <returns>An <see cref="IEnumerator{T}"/> object that can be used to iterate through the collection.</returns>
        public IEnumerator <ReflogEntry> GetEnumerator()
        {
            var entries = new List <ReflogEntry>();

            using (ReferenceSafeHandle reference = Proxy.git_reference_lookup(repo.Handle, canonicalName, true))
                using (ReflogSafeHandle reflog = Proxy.git_reflog_read(reference))
                {
                    var entriesCount = Proxy.git_reflog_entrycount(reflog);

                    for (int i = 0; i < entriesCount; i++)
                    {
                        ReflogEntrySafeHandle handle = Proxy.git_reflog_entry_byindex(reflog, i);
                        entries.Add(new ReflogEntry(handle));
                    }
                }

            return(entries.GetEnumerator());
        }
Example #26
0
        /// <summary>
        ///   Renames an existing local branch with a new name.
        /// </summary>
        /// <param name = "branch">The current local branch.</param>
        /// <param name = "newName">The new name the existing branch should bear.</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 Move(Branch branch, string newName, 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));
            }

            using (ReferenceSafeHandle referencePtr = repo.Refs.RetrieveReferencePtr("refs/heads/" + branch.Name))
            {
                using (ReferenceSafeHandle ref_out = Proxy.git_branch_move(referencePtr, newName, allowOverwrite))
                {
                }
            }

            return(this[newName]);
        }
Example #27
0
        /// <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="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, bool allowOverwrite)
        {
            Ensure.ArgumentNotNull(branch, "branch");
            Ensure.ArgumentNotNullOrEmptyString(newName, "newName");

            if (branch.IsRemote)
            {
                throw new LibGit2SharpException("Cannot rename branch '{0}'. It's a remote tracking branch.",
                                                branch.FriendlyName);
            }

            using (ReferenceSafeHandle referencePtr = repo.Refs.RetrieveReferencePtr(Reference.LocalBranchPrefix + branch.FriendlyName))
            {
                using (Proxy.git_branch_move(referencePtr, newName, allowOverwrite))
                { }
            }

            var newBranch = this[newName];

            return(newBranch);
        }
        /// <summary>
        ///   Creates a direct or symbolic reference with the specified name and target
        /// </summary>
        /// <param name = "name">The name of the reference to create.</param>
        /// <param name = "target">The target which can be either a sha or the canonical name of another 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 Reference Create(string name, string target, bool allowOverwrite = false)
        {
            Ensure.ArgumentNotNullOrEmptyString(name, "name");
            Ensure.ArgumentNotNullOrEmptyString(target, "target");

            ObjectId id;
            Func <string, bool, ReferenceSafeHandle> referenceCreator;

            if (ObjectId.TryParse(target, out id))
            {
                referenceCreator = (n, o) => CreateDirectReference(n, id, o);
            }
            else
            {
                referenceCreator = (n, o) => CreateSymbolicReference(n, target, o);
            }

            using (ReferenceSafeHandle handle = referenceCreator(name, allowOverwrite))
            {
                return(Reference.BuildFromPtr <Reference>(handle, repo));
            }
        }
Example #29
0
        internal static T BuildFromPtr <T>(ReferenceSafeHandle handle, Repository repo) where T : Reference
        {
            GitReferenceType type = Proxy.git_reference_type(handle);
            string           name = Proxy.git_reference_name(handle);

            Reference reference;

            switch (type)
            {
            case GitReferenceType.Symbolic:
                string targetIdentifier = Proxy.git_reference_target(handle);

                using (ReferenceSafeHandle resolvedHandle = Proxy.git_reference_resolve(handle))
                {
                    if (resolvedHandle == null)
                    {
                        reference = new SymbolicReference(name, targetIdentifier, null);
                        break;
                    }

                    var targetRef = BuildFromPtr <DirectReference>(resolvedHandle, repo);
                    reference = new SymbolicReference(name, targetIdentifier, targetRef);
                    break;
                }

            case GitReferenceType.Oid:
                ObjectId targetOid = Proxy.git_reference_oid(handle);

                reference = new DirectReference(name, repo, targetOid);
                break;

            default:
                throw new LibGit2SharpException(String.Format(CultureInfo.InvariantCulture, "Unable to build a new reference from a type '{0}'.", type));
            }

            return(reference as T);
        }
Example #30
0
        internal ReferenceSafeHandle RetrieveReferencePtr(string referenceName, bool shouldThrowIfNotFound = true)
        {
            ReferenceSafeHandle reference = Proxy.git_reference_lookup(repo.Handle, referenceName, shouldThrowIfNotFound);

            return(reference);
        }