private boolean commitIndex(Repository db, DirCache index, String author, String message) throws IOException, ConcurrentRefUpdateException { boolean success = false; ObjectId headId = db.resolve(BRANCH + "^{commit}"); if (headId == null) { // create the branch createTicketsBranch(db); headId = db.resolve(BRANCH + "^{commit}"); } try (ObjectInserter odi = db.newObjectInserter()) { // Create the in-memory index of the new/updated ticket ObjectId indexTreeId = index.writeTree(odi); // Create a commit object PersonIdent ident = new PersonIdent(author, "gitblit@localhost"); CommitBuilder commit = new CommitBuilder(); commit.setAuthor(ident); commit.setCommitter(ident); commit.setEncoding(Constants.ENCODING); commit.setMessage(message); commit.setParentId(headId); commit.setTreeId(indexTreeId); // Insert the commit into the repository ObjectId commitId = odi.insert(commit); odi.flush(); try (RevWalk revWalk = new RevWalk(db)) { RevCommit revCommit = revWalk.parseCommit(commitId); RefUpdate ru = db.updateRef(BRANCH); ru.setNewObjectId(commitId); ru.setExpectedOldObjectId(headId); ru.setRefLogMessage("commit: " + revCommit.getShortMessage(), false); Result rc = ru.forceUpdate(); switch (rc) { case NEW: case FORCED: case FAST_FORWARD: success = true; break; case REJECTED: case LOCK_FAILURE: throw new ConcurrentRefUpdateException( JGitText.get().couldNotLockHEAD, ru.getRef(), rc); default: throw new JGitInternalException( MessageFormat.format( JGitText.get().updatingRefFailed, BRANCH, commitId.toString(), rc)); } } } return success; }
/** * Executes the {@code commit} 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 {@link #call()}) * * @return a {@link RevCommit} object representing the successful commit. * @throws NoHeadException when called on a git repo without a HEAD reference * @throws NoMessageException when called without specifying a commit message * @throws UnmergedPathsException when the current index contained unmerged paths (conflicts) * @throws ConcurrentRefUpdateException when HEAD or branch ref is updated concurrently by someone * else * @throws WrongRepositoryStateException when repository is not in the right state for committing * @throws AbortedByHookException if there are either pre-commit or commit-msg hooks present in * the repository and one of them rejects the commit. */ public RevCommit call() throws GitAPIException, NoHeadException, NoMessageException, UnmergedPathsException, ConcurrentRefUpdateException, WrongRepositoryStateException, AbortedByHookException { checkCallable(); Collections.sort(only); try (RevWalk rw = new RevWalk(repo)) { RepositoryState state = repo.getRepositoryState(); if (!state.canCommit()) throw new WrongRepositoryStateException( MessageFormat.format(JGitText.get().cannotCommitOnARepoWithState, state.name())); if (!noVerify) { Hooks.preCommit(repo, hookOutRedirect).call(); } processOptions(state, rw); if (all && !repo.isBare() && repo.getWorkTree() != null) { try (Git git = new Git(repo)) { git.add() .addFilepattern(".") // $NON-NLS-1$ .setUpdate(true) .call(); } catch (NoFilepatternException e) { // should really not happen throw new JGitInternalException(e.getMessage(), 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}"); // $NON-NLS-1$ if (headId == null && amend) throw new WrongRepositoryStateException(JGitText.get().commitAmendOnInitialNotPossible); if (headId != null) if (amend) { RevCommit previousCommit = rw.parseCommit(headId); for (RevCommit p : previousCommit.getParents()) parents.add(p.getId()); if (author == null) author = previousCommit.getAuthorIdent(); } else { parents.add(0, headId); } if (!noVerify) { message = Hooks.commitMsg(repo, hookOutRedirect).setCommitMessage(message).call(); } // lock the index DirCache index = repo.lockDirCache(); try (ObjectInserter odi = repo.newObjectInserter()) { if (!only.isEmpty()) index = createTemporaryIndex(headId, index, rw); // 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 CommitBuilder commit = new CommitBuilder(); commit.setCommitter(committer); commit.setAuthor(author); commit.setMessage(message); commit.setParentIds(parents); commit.setTreeId(indexTreeId); ObjectId commitId = odi.insert(commit); odi.flush(); RevCommit revCommit = rw.parseCommit(commitId); RefUpdate ru = repo.updateRef(Constants.HEAD); ru.setNewObjectId(commitId); if (reflogComment != null) { ru.setRefLogMessage(reflogComment, false); } else { String prefix = amend ? "commit (amend): " //$NON-NLS-1$ : parents.size() == 0 ? "commit (initial): " //$NON-NLS-1$ : "commit: "; //$NON-NLS-1$ ru.setRefLogMessage(prefix + revCommit.getShortMessage(), false); } if (headId != null) ru.setExpectedOldObjectId(headId); else ru.setExpectedOldObjectId(ObjectId.zeroId()); Result rc = ru.forceUpdate(); switch (rc) { case NEW: case FORCED: case FAST_FORWARD: { setCallable(false); if (state == RepositoryState.MERGING_RESOLVED || isMergeDuringRebase(state)) { // 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); } else if (state == RepositoryState.REVERTING_RESOLVED) { repo.writeMergeCommitMsg(null); repo.writeRevertHead(null); } return revCommit; } case REJECTED: case 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 { index.unlock(); } } catch (UnmergedPathException e) { throw new UnmergedPathsException(e); } catch (IOException e) { throw new JGitInternalException( JGitText.get().exceptionCaughtDuringExecutionOfCommitCommand, e); } }