/// <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); } }