public CherryPickResult call() throws GitAPIException {
RevCommit newHead = null;
List<Ref> cherryPickedRefs = new LinkedList<Ref>();
checkCallable();
RevWalk revWalk = new RevWalk(repo);
try {
// get the head commit
Ref headRef = repo.getRef(Constants.HEAD);
if (headRef == null)
throw new NoHeadException(
JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported);
RevCommit headCommit = revWalk.parseCommit(headRef.getObjectId());
newHead = headCommit;
// loop through all refs to be cherry-picked
for (Ref src : commits) {
// get the commit to be cherry-picked
// handle annotated tags
ObjectId srcObjectId = src.getPeeledObjectId();
if (srcObjectId == null)
srcObjectId = src.getObjectId();
RevCommit srcCommit = revWalk.parseCommit(srcObjectId);
// get the parent of the commit to cherry-pick
if (srcCommit.getParentCount() != 1)
throw new MultipleParentsNotAllowedException(
MessageFormat.format(
JGitText.get().canOnlyCherryPickCommitsWithOneParent,
srcCommit.name(),
Integer.valueOf(srcCommit.getParentCount())));
RevCommit srcParent = srcCommit.getParent(0);
revWalk.parseHeaders(srcParent);
ResolveMerger merger = (ResolveMerger) MergeStrategy.RESOLVE
.newMerger(repo);
merger.setWorkingTreeIterator(new FileTreeIterator(repo));
merger.setBase(srcParent.getTree());
if (merger.merge(headCommit, srcCommit)) {
if (AnyObjectId.equals(headCommit.getTree().getId(), merger
.getResultTreeId()))
continue;
DirCacheCheckout dco = new DirCacheCheckout(repo,
headCommit.getTree(), repo.lockDirCache(),
merger.getResultTreeId());
dco.setFailOnConflict(true);
dco.checkout();
newHead = new Git(getRepository()).commit()
.setMessage(srcCommit.getFullMessage())
.setReflogComment(
"cherry-pick: "
+ srcCommit.getShortMessage())
.setAuthor(srcCommit.getAuthorIdent()).call();
cherryPickedRefs.add(src);
} else {
if (merger.failed())
return new CherryPickResult(merger.getFailingPaths());
// there are merge conflicts
String message = new MergeMessageFormatter()
.formatWithConflicts(srcCommit.getFullMessage(),
merger.getUnmergedPaths());
repo.writeCherryPickHead(srcCommit.getId());
repo.writeMergeCommitMsg(message);
return CherryPickResult.CONFLICT;
}
}
} catch (IOException e) {
throw new JGitInternalException(
MessageFormat.format(
JGitText.get().exceptionCaughtDuringExecutionOfCherryPickCommand,
e), e);
} finally {
revWalk.release();
}
return new CherryPickResult(newHead, cherryPickedRefs);
}