Exemplo n.º 1
0
        /// <exception cref="System.IO.IOException"></exception>
        private void CommitNoteMap(RevWalk walk, NoteMap map, RevCommit notesCommit, ObjectInserter
                                   inserter, string msg)
        {
            // commit the note
            NGit.CommitBuilder builder = new NGit.CommitBuilder();
            builder.TreeId    = map.WriteTree(inserter);
            builder.Author    = new PersonIdent(repo);
            builder.Committer = builder.Author;
            builder.Message   = msg;
            if (notesCommit != null)
            {
                builder.SetParentIds(notesCommit);
            }
            ObjectId commit = inserter.Insert(builder);

            inserter.Flush();
            RefUpdate refUpdate = repo.UpdateRef(notesRef);

            if (notesCommit != null)
            {
                refUpdate.SetExpectedOldObjectId(notesCommit);
            }
            else
            {
                refUpdate.SetExpectedOldObjectId(ObjectId.ZeroId);
            }
            refUpdate.SetNewObjectId(commit);
            refUpdate.Update(walk);
        }
Exemplo n.º 2
0
        /// <exception cref="System.IO.IOException"></exception>
        private void CheckoutCommit(RevCommit commit)
        {
            try
            {
                RevCommit        head = walk.ParseCommit(repo.Resolve(Constants.HEAD));
                DirCacheCheckout dco  = new DirCacheCheckout(repo, head.Tree, repo.LockDirCache(),
                                                             commit.Tree);
                dco.SetFailOnConflict(true);
                dco.Checkout();
                // update the HEAD
                RefUpdate refUpdate = repo.UpdateRef(Constants.HEAD, true);
                refUpdate.SetExpectedOldObjectId(head);
                refUpdate.SetNewObjectId(commit);
                RefUpdate.Result res = refUpdate.ForceUpdate();
                switch (res)
                {
                case RefUpdate.Result.FAST_FORWARD:
                case RefUpdate.Result.NO_CHANGE:
                case RefUpdate.Result.FORCED:
                {
                    break;
                }

                default:
                {
                    throw new IOException("Could not rewind to upstream commit");
                }
                }
            }
            finally
            {
                walk.Release();
                monitor.EndTask();
            }
        }
Exemplo n.º 3
0
        /// <exception cref="System.IO.IOException"></exception>
        /// <exception cref="NGit.Api.Errors.ConcurrentRefUpdateException"></exception>
        private void UpdateHead(StringBuilder refLogMessage, ObjectId newHeadId, ObjectId
                                oldHeadID)
        {
            RefUpdate refUpdate = repo.UpdateRef(Constants.HEAD);

            refUpdate.SetNewObjectId(newHeadId);
            refUpdate.SetRefLogMessage(refLogMessage.ToString(), false);
            refUpdate.SetExpectedOldObjectId(oldHeadID);
            RefUpdate.Result rc = refUpdate.Update();
            switch (rc)
            {
            case RefUpdate.Result.NEW:
            case RefUpdate.Result.FAST_FORWARD:
            {
                return;
            }

            case RefUpdate.Result.REJECTED:
            case RefUpdate.Result.LOCK_FAILURE:
            {
                throw new ConcurrentRefUpdateException(JGitText.Get().couldNotLockHEAD, refUpdate
                                                       .GetRef(), rc);
            }

            default:
            {
                throw new JGitInternalException(MessageFormat.Format(JGitText.Get().updatingRefFailed
                                                                     , Constants.HEAD, newHeadId.ToString(), rc));
            }
            }
        }
Exemplo n.º 4
0
        /// <exception cref="System.IO.IOException"></exception>
        /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception>
        private RevCommit TryFastForward(string headName, RevCommit oldCommit, RevCommit
                                         newCommit)
        {
            bool tryRebase = false;

            foreach (RevCommit parentCommit in newCommit.Parents)
            {
                if (parentCommit.Equals(oldCommit))
                {
                    tryRebase = true;
                }
            }
            if (!tryRebase)
            {
                return(null);
            }
            CheckoutCommand co = new CheckoutCommand(repo);

            try
            {
                co.SetName(newCommit.Name).Call();
                if (headName.StartsWith(Constants.R_HEADS))
                {
                    RefUpdate rup = repo.UpdateRef(headName);
                    rup.SetExpectedOldObjectId(oldCommit);
                    rup.SetNewObjectId(newCommit);
                    rup.SetRefLogMessage("Fast-foward from " + oldCommit.Name + " to " + newCommit.Name
                                         , false);
                    RefUpdate.Result res = rup.Update(walk);
                    switch (res)
                    {
                    case RefUpdate.Result.FAST_FORWARD:
                    case RefUpdate.Result.NO_CHANGE:
                    case RefUpdate.Result.FORCED:
                    {
                        break;
                    }

                    default:
                    {
                        throw new IOException("Could not fast-forward");
                    }
                    }
                }
                return(newCommit);
            }
            catch (RefAlreadyExistsException e)
            {
                throw new JGitInternalException(e.Message, e);
            }
            catch (RefNotFoundException e)
            {
                throw new JGitInternalException(e.Message, e);
            }
            catch (InvalidRefNameException e)
            {
                throw new JGitInternalException(e.Message, e);
            }
        }
Exemplo n.º 5
0
        /// <exception cref="System.IO.IOException"></exception>
        private RefUpdate CreateRefUpdate(Ref stashRef)
        {
            RefUpdate update = repo.UpdateRef(Constants.R_STASH);

            update.DisableRefLog();
            update.SetExpectedOldObjectId(stashRef.GetObjectId());
            update.SetForceUpdate(true);
            return(update);
        }
Exemplo n.º 6
0
        /// <exception cref="System.IO.IOException"></exception>
        private void UpdateStashRef(ObjectId commitId, PersonIdent refLogIdent, string refLogMessage
                                    )
        {
            Ref       currentRef = repo.GetRef(@ref);
            RefUpdate refUpdate  = repo.UpdateRef(@ref);

            refUpdate.SetNewObjectId(commitId);
            refUpdate.SetRefLogIdent(refLogIdent);
            refUpdate.SetRefLogMessage(refLogMessage, false);
            if (currentRef != null)
            {
                refUpdate.SetExpectedOldObjectId(currentRef.GetObjectId());
            }
            else
            {
                refUpdate.SetExpectedOldObjectId(ObjectId.ZeroId);
            }
            refUpdate.ForceUpdate();
        }
Exemplo n.º 7
0
        public virtual void TestUpdateRefLockFailureWrongOldValue()
        {
            ObjectId  pid       = db.Resolve("refs/heads/master");
            RefUpdate updateRef = db.UpdateRef("refs/heads/master");

            updateRef.SetNewObjectId(pid);
            updateRef.SetExpectedOldObjectId(db.Resolve("refs/heads/master^"));
            RefUpdate.Result update = updateRef.Update();
            NUnit.Framework.Assert.AreEqual(RefUpdate.Result.LOCK_FAILURE, update);
            NUnit.Framework.Assert.AreEqual(pid, db.Resolve("refs/heads/master"));
        }
        /// <summary>Execute this command during a receive-pack session.</summary>
        /// <remarks>
        /// Execute this command during a receive-pack session.
        /// <p>
        /// Sets the status of the command as a side effect.
        /// </remarks>
        /// <param name="rp">receive-pack session.</param>
        /// <since>2.0</since>
        public virtual void Execute(BaseReceivePack rp)
        {
            try
            {
                RefUpdate ru = rp.GetRepository().UpdateRef(GetRefName());
                ru.SetRefLogIdent(rp.GetRefLogIdent());
                switch (GetType())
                {
                case ReceiveCommand.Type.DELETE:
                {
                    if (!ObjectId.ZeroId.Equals(GetOldId()))
                    {
                        // We can only do a CAS style delete if the client
                        // didn't bork its delete request by sending the
                        // wrong zero id rather than the advertised one.
                        //
                        ru.SetExpectedOldObjectId(GetOldId());
                    }
                    ru.SetForceUpdate(true);
                    SetResult(ru.Delete(rp.GetRevWalk()));
                    break;
                }

                case ReceiveCommand.Type.CREATE:
                case ReceiveCommand.Type.UPDATE:
                case ReceiveCommand.Type.UPDATE_NONFASTFORWARD:
                {
                    ru.SetForceUpdate(rp.IsAllowNonFastForwards());
                    ru.SetExpectedOldObjectId(GetOldId());
                    ru.SetNewObjectId(GetNewId());
                    ru.SetRefLogMessage("push", true);
                    SetResult(ru.Update(rp.GetRevWalk()));
                    break;
                }
                }
            }
            catch (IOException err)
            {
                Reject(err);
            }
        }
Exemplo n.º 9
0
        public virtual void TestCreateFromLightweightTag()
        {
            RefUpdate rup = db.UpdateRef("refs/tags/V10");

            rup.SetNewObjectId(initialCommit);
            rup.SetExpectedOldObjectId(ObjectId.ZeroId);
            rup.Update();
            Ref branch = git.BranchCreate().SetName("FromLightweightTag").SetStartPoint("refs/tags/V10"
                                                                                        ).Call();

            NUnit.Framework.Assert.AreEqual(initialCommit.Id, branch.GetObjectId());
        }
Exemplo n.º 10
0
        public virtual void TestUpdateRefForwardWithCheck1()
        {
            ObjectId  ppid      = db.Resolve("refs/heads/master^");
            ObjectId  pid       = db.Resolve("refs/heads/master");
            RefUpdate updateRef = db.UpdateRef("refs/heads/master");

            updateRef.SetNewObjectId(ppid);
            updateRef.SetForceUpdate(true);
            RefUpdate.Result update = updateRef.Update();
            NUnit.Framework.Assert.AreEqual(RefUpdate.Result.FORCED, update);
            NUnit.Framework.Assert.AreEqual(ppid, db.Resolve("refs/heads/master"));
            // real test
            RefUpdate updateRef2 = db.UpdateRef("refs/heads/master");

            updateRef2.SetExpectedOldObjectId(ppid);
            updateRef2.SetNewObjectId(pid);
            RefUpdate.Result update2 = updateRef2.Update();
            NUnit.Framework.Assert.AreEqual(RefUpdate.Result.FAST_FORWARD, update2);
            NUnit.Framework.Assert.AreEqual(pid, db.Resolve("refs/heads/master"));
        }
Exemplo n.º 11
0
        /// <summary>
        /// Executes the
        /// <code>Merge</code>
        /// command with all the options and parameters
        /// collected by the setter methods (e.g.
        /// <see cref="Include(NGit.Ref)">Include(NGit.Ref)</see>
        /// ) of this
        /// class. Each instance of this class should only be used for one invocation
        /// of the command. Don't call this method twice on an instance.
        /// </summary>
        /// <returns>the result of the merge</returns>
        /// <exception cref="NGit.Api.Errors.NoHeadException"></exception>
        /// <exception cref="NGit.Api.Errors.ConcurrentRefUpdateException"></exception>
        /// <exception cref="NGit.Api.Errors.CheckoutConflictException"></exception>
        /// <exception cref="NGit.Api.Errors.InvalidMergeHeadsException"></exception>
        /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException"></exception>
        /// <exception cref="NGit.Api.Errors.NoMessageException"></exception>
        public override MergeCommandResult Call()
        {
            CheckCallable();
            if (commits.Count != 1)
            {
                throw new InvalidMergeHeadsException(commits.IsEmpty() ? JGitText.Get().noMergeHeadSpecified
                                         : MessageFormat.Format(JGitText.Get().mergeStrategyDoesNotSupportHeads, mergeStrategy
                                                                .GetName(), Sharpen.Extensions.ValueOf(commits.Count)));
            }
            RevWalk revWalk = null;

            try
            {
                Ref head = repo.GetRef(Constants.HEAD);
                if (head == null)
                {
                    throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported
                                              );
                }
                StringBuilder refLogMessage = new StringBuilder("merge ");
                // Check for FAST_FORWARD, ALREADY_UP_TO_DATE
                revWalk = new RevWalk(repo);
                // we know for now there is only one commit
                Ref @ref = commits[0];
                refLogMessage.Append(@ref.GetName());
                // handle annotated tags
                ObjectId objectId = @ref.GetPeeledObjectId();
                if (objectId == null)
                {
                    objectId = @ref.GetObjectId();
                }
                RevCommit srcCommit = revWalk.LookupCommit(objectId);
                ObjectId  headId    = head.GetObjectId();
                if (headId == null)
                {
                    revWalk.ParseHeaders(srcCommit);
                    DirCacheCheckout dco = new DirCacheCheckout(repo, repo.LockDirCache(), srcCommit.
                                                                Tree);
                    dco.SetFailOnConflict(true);
                    dco.Checkout();
                    RefUpdate refUpdate = repo.UpdateRef(head.GetTarget().GetName());
                    refUpdate.SetNewObjectId(objectId);
                    refUpdate.SetExpectedOldObjectId(null);
                    refUpdate.SetRefLogMessage("initial pull", false);
                    if (refUpdate.Update() != RefUpdate.Result.NEW)
                    {
                        throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported
                                                  );
                    }
                    SetCallable(false);
                    return(new MergeCommandResult(srcCommit, srcCommit, new ObjectId[] { null, srcCommit }, MergeStatus.FAST_FORWARD, mergeStrategy, null, null));
                }
                RevCommit headCommit = revWalk.LookupCommit(headId);
                if (revWalk.IsMergedInto(srcCommit, headCommit))
                {
                    SetCallable(false);
                    return(new MergeCommandResult(headCommit, srcCommit, new ObjectId[] { headCommit,
                                                                                          srcCommit }, MergeStatus.ALREADY_UP_TO_DATE, mergeStrategy, null, null));
                }
                else
                {
                    if (revWalk.IsMergedInto(headCommit, srcCommit))
                    {
                        // FAST_FORWARD detected: skip doing a real merge but only
                        // update HEAD
                        refLogMessage.Append(": " + MergeStatus.FAST_FORWARD);
                        DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.Tree, repo.LockDirCache
                                                                        (), srcCommit.Tree);
                        dco.SetFailOnConflict(true);
                        dco.Checkout();
                        UpdateHead(refLogMessage, srcCommit, headId);
                        SetCallable(false);
                        return(new MergeCommandResult(srcCommit, srcCommit, new ObjectId[] { headCommit,
                                                                                             srcCommit }, MergeStatus.FAST_FORWARD, mergeStrategy, null, null));
                    }
                    else
                    {
                        repo.WriteMergeCommitMsg(new MergeMessageFormatter().Format(commits, head));
                        repo.WriteMergeHeads(Arrays.AsList(@ref.GetObjectId()));
                        ThreeWayMerger merger = (ThreeWayMerger)mergeStrategy.NewMerger(repo);
                        bool           noProblems;
                        IDictionary <string, MergeResult <NGit.Diff.Sequence> > lowLevelResults = null;
                        IDictionary <string, ResolveMerger.MergeFailureReason>  failingPaths    = null;
                        if (merger is ResolveMerger)
                        {
                            ResolveMerger resolveMerger = (ResolveMerger)merger;
                            resolveMerger.SetCommitNames(new string[] { "BASE", "HEAD", @ref.GetName() });
                            resolveMerger.SetWorkingTreeIterator(new FileTreeIterator(repo));
                            noProblems      = merger.Merge(headCommit, srcCommit);
                            lowLevelResults = resolveMerger.GetMergeResults();
                            failingPaths    = resolveMerger.GetFailingPaths();
                        }
                        else
                        {
                            noProblems = merger.Merge(headCommit, srcCommit);
                        }
                        if (noProblems)
                        {
                            DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.Tree, repo.LockDirCache
                                                                            (), merger.GetResultTreeId());
                            dco.SetFailOnConflict(true);
                            dco.Checkout();
                            RevCommit newHead = new Git(GetRepository()).Commit().Call();
                            return(new MergeCommandResult(newHead.Id, null, new ObjectId[] { headCommit.Id, srcCommit
                                                                                             .Id }, MergeStatus.MERGED, mergeStrategy, null, null));
                        }
                        else
                        {
                            if (failingPaths != null)
                            {
                                repo.WriteMergeCommitMsg(null);
                                repo.WriteMergeHeads(null);
                                return(new MergeCommandResult(null, merger.GetBaseCommit(0, 1), new ObjectId[] {
                                    headCommit.Id, srcCommit.Id
                                }, MergeStatus.FAILED, mergeStrategy, lowLevelResults
                                                              , null));
                            }
                            else
                            {
                                return(new MergeCommandResult(null, merger.GetBaseCommit(0, 1), new ObjectId[] {
                                    headCommit.Id, srcCommit.Id
                                }, MergeStatus.CONFLICTING, mergeStrategy, lowLevelResults
                                                              , null));
                            }
                        }
                    }
                }
            }
            catch (IOException e)
            {
                throw new JGitInternalException(MessageFormat.Format(JGitText.Get().exceptionCaughtDuringExecutionOfMergeCommand
                                                                     , e), e);
            }
            finally
            {
                if (revWalk != null)
                {
                    revWalk.Release();
                }
            }
        }
        /// <exception cref="System.IO.IOException"></exception>
        protected internal override RefUpdate.Result DoRename()
        {
            if (source.GetRef().IsSymbolic())
            {
                return(RefUpdate.Result.IO_FAILURE);
            }
            // not supported
            objId      = source.GetOldObjectId();
            updateHEAD = NeedToUpdateHEAD();
            tmp        = refdb.NewTemporaryUpdate();
            RevWalk rw = new RevWalk(refdb.GetRepository());

            try
            {
                // First backup the source so its never unreachable.
                tmp.SetNewObjectId(objId);
                tmp.SetForceUpdate(true);
                tmp.DisableRefLog();
                switch (tmp.Update(rw))
                {
                case RefUpdate.Result.NEW:
                case RefUpdate.Result.FORCED:
                case RefUpdate.Result.NO_CHANGE:
                {
                    break;
                }

                default:
                {
                    return(tmp.GetResult());

                    break;
                }
                }
                // Save the source's log under the temporary name, we must do
                // this before we delete the source, otherwise we lose the log.
                if (!RenameLog(source, tmp))
                {
                    return(RefUpdate.Result.IO_FAILURE);
                }
                // If HEAD has to be updated, link it now to destination.
                // We have to link before we delete, otherwise the delete
                // fails because its the current branch.
                RefUpdate dst = destination;
                if (updateHEAD)
                {
                    if (!LinkHEAD(destination))
                    {
                        RenameLog(tmp, source);
                        return(RefUpdate.Result.LOCK_FAILURE);
                    }
                    // Replace the update operation so HEAD will log the rename.
                    dst = ((RefDirectoryUpdate)refdb.NewUpdate(Constants.HEAD, false));
                    dst.SetRefLogIdent(destination.GetRefLogIdent());
                    dst.SetRefLogMessage(destination.GetRefLogMessage(), false);
                }
                // Delete the source name so its path is free for replacement.
                source.SetExpectedOldObjectId(objId);
                source.SetForceUpdate(true);
                source.DisableRefLog();
                if (source.Delete(rw) != RefUpdate.Result.FORCED)
                {
                    RenameLog(tmp, source);
                    if (updateHEAD)
                    {
                        LinkHEAD(source);
                    }
                    return(source.GetResult());
                }
                // Move the log to the destination.
                if (!RenameLog(tmp, destination))
                {
                    RenameLog(tmp, source);
                    source.SetExpectedOldObjectId(ObjectId.ZeroId);
                    source.SetNewObjectId(objId);
                    source.Update(rw);
                    if (updateHEAD)
                    {
                        LinkHEAD(source);
                    }
                    return(RefUpdate.Result.IO_FAILURE);
                }
                // Create the destination, logging the rename during the creation.
                dst.SetExpectedOldObjectId(ObjectId.ZeroId);
                dst.SetNewObjectId(objId);
                if (dst.Update(rw) != RefUpdate.Result.NEW)
                {
                    // If we didn't create the destination we have to undo
                    // our work. Put the log back and restore source.
                    if (RenameLog(destination, tmp))
                    {
                        RenameLog(tmp, source);
                    }
                    source.SetExpectedOldObjectId(ObjectId.ZeroId);
                    source.SetNewObjectId(objId);
                    source.Update(rw);
                    if (updateHEAD)
                    {
                        LinkHEAD(source);
                    }
                    return(dst.GetResult());
                }
                return(RefUpdate.Result.RENAMED);
            }
            finally
            {
                // Always try to free the temporary name.
                try
                {
                    refdb.Delete(tmp);
                }
                catch (IOException)
                {
                    FileUtils.Delete(refdb.FileFor(tmp.GetName()));
                }
                rw.Release();
            }
        }
Exemplo n.º 13
0
        /// <summary>
        /// Executes the
        /// <code>commit</code>
        /// command with all the options and parameters
        /// collected by the setter methods of this class. Each instance of this
        /// class should only be used for one invocation of the command (means: one
        /// call to
        /// <see cref="Call()">Call()</see>
        /// )
        /// </summary>
        /// <returns>
        /// a
        /// <see cref="NGit.Revwalk.RevCommit">NGit.Revwalk.RevCommit</see>
        /// object representing the successful commit.
        /// </returns>
        /// <exception cref="NGit.Api.Errors.NoHeadException">when called on a git repo without a HEAD reference
        ///     </exception>
        /// <exception cref="NGit.Api.Errors.NoMessageException">when called without specifying a commit message
        ///     </exception>
        /// <exception cref="NGit.Api.Errors.UnmergedPathsException">when the current index contained unmerged paths (conflicts)
        ///     </exception>
        /// <exception cref="NGit.Api.Errors.ConcurrentRefUpdateException">
        /// when HEAD or branch ref is updated concurrently by someone
        /// else
        /// </exception>
        /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException">when repository is not in the right state for committing
        ///     </exception>
        /// <exception cref="NGit.Api.Errors.GitAPIException"></exception>
        public override RevCommit Call()
        {
            CheckCallable();
            RepositoryState state = repo.GetRepositoryState();

            if (!state.CanCommit())
            {
                throw new WrongRepositoryStateException(MessageFormat.Format(JGitText.Get().cannotCommitOnARepoWithState
                                                                             , state.Name()));
            }
            ProcessOptions(state);
            try
            {
                if (all && !repo.IsBare && repo.WorkTree != null)
                {
                    Git git = new Git(repo);
                    try
                    {
                        git.Add().AddFilepattern(".").SetUpdate(true).Call();
                    }
                    catch (NoFilepatternException e)
                    {
                        // should really not happen
                        throw new JGitInternalException(e.Message, e);
                    }
                }
                Ref head = repo.GetRef(Constants.HEAD);
                if (head == null)
                {
                    throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported
                                              );
                }
                // determine the current HEAD and the commit it is referring to
                ObjectId headId = repo.Resolve(Constants.HEAD + "^{commit}");
                if (headId == null && amend)
                {
                    throw new WrongRepositoryStateException(JGitText.Get().commitAmendOnInitialNotPossible
                                                            );
                }
                if (headId != null)
                {
                    if (amend)
                    {
                        RevCommit   previousCommit = new RevWalk(repo).ParseCommit(headId);
                        RevCommit[] p = previousCommit.Parents;
                        for (int i = 0; i < p.Length; i++)
                        {
                            parents.Add(0, p[i].Id);
                        }
                        if (author == null)
                        {
                            author = previousCommit.GetAuthorIdent();
                        }
                    }
                    else
                    {
                        parents.Add(0, headId);
                    }
                }
                // lock the index
                DirCache index = repo.LockDirCache();
                try
                {
                    if (!only.IsEmpty())
                    {
                        index = CreateTemporaryIndex(headId, index);
                    }
                    ObjectInserter odi = repo.NewObjectInserter();
                    try
                    {
                        // Write the index as tree to the object database. This may
                        // fail for example when the index contains unmerged paths
                        // (unresolved conflicts)
                        ObjectId indexTreeId = index.WriteTree(odi);
                        if (insertChangeId)
                        {
                            InsertChangeId(indexTreeId);
                        }
                        // Create a Commit object, populate it and write it
                        NGit.CommitBuilder commit = new NGit.CommitBuilder();
                        commit.Committer = committer;
                        commit.Author    = author;
                        commit.Message   = message;
                        commit.SetParentIds(parents);
                        commit.TreeId = indexTreeId;
                        ObjectId commitId = odi.Insert(commit);
                        odi.Flush();
                        RevWalk revWalk = new RevWalk(repo);
                        try
                        {
                            RevCommit revCommit = revWalk.ParseCommit(commitId);
                            RefUpdate ru        = repo.UpdateRef(Constants.HEAD);
                            ru.SetNewObjectId(commitId);
                            if (reflogComment != null)
                            {
                                ru.SetRefLogMessage(reflogComment, false);
                            }
                            else
                            {
                                string prefix = amend ? "commit (amend): " : "commit: ";
                                ru.SetRefLogMessage(prefix + revCommit.GetShortMessage(), false);
                            }
                            if (headId != null)
                            {
                                ru.SetExpectedOldObjectId(headId);
                            }
                            else
                            {
                                ru.SetExpectedOldObjectId(ObjectId.ZeroId);
                            }
                            RefUpdate.Result rc = ru.ForceUpdate();
                            switch (rc)
                            {
                            case RefUpdate.Result.NEW:
                            case RefUpdate.Result.FORCED:
                            case RefUpdate.Result.FAST_FORWARD:
                            {
                                SetCallable(false);
                                if (state == RepositoryState.MERGING_RESOLVED)
                                {
                                    // Commit was successful. Now delete the files
                                    // used for merge commits
                                    repo.WriteMergeCommitMsg(null);
                                    repo.WriteMergeHeads(null);
                                }
                                else
                                {
                                    if (state == RepositoryState.CHERRY_PICKING_RESOLVED)
                                    {
                                        repo.WriteMergeCommitMsg(null);
                                        repo.WriteCherryPickHead(null);
                                    }
                                }
                                return(revCommit);
                            }

                            case RefUpdate.Result.REJECTED:
                            case RefUpdate.Result.LOCK_FAILURE:
                            {
                                throw new ConcurrentRefUpdateException(JGitText.Get().couldNotLockHEAD, ru.GetRef
                                                                           (), rc);
                            }

                            default:
                            {
                                throw new JGitInternalException(MessageFormat.Format(JGitText.Get().updatingRefFailed
                                                                                     , Constants.HEAD, commitId.ToString(), rc));
                            }
                            }
                        }
                        finally
                        {
                            revWalk.Release();
                        }
                    }
                    finally
                    {
                        odi.Release();
                    }
                }
                finally
                {
                    index.Unlock();
                }
            }
            catch (UnmergedPathException e)
            {
                throw new UnmergedPathsException(e);
            }
            catch (IOException e)
            {
                throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfCommitCommand
                                                , e);
            }
        }