in git-server/src/main/java/jetbrains/buildServer/buildTriggers/vcs/git/GitMergeSupport.java [172:239]
private ObjectId mergeCommits(@NotNull GitVcsRoot gitRoot,
@NotNull Repository db,
@NotNull RevCommit srcCommit,
@NotNull RevCommit dstCommit,
@NotNull String message,
@NotNull MergeOptions options) throws IOException, MergeFailedException {
if (!alwaysCreateMergeCommit(options)) {
RevWalk walk = new RevWalk(db);
try {
if (walk.isMergedInto(walk.parseCommit(dstCommit), walk.parseCommit(srcCommit))) {
LOG.debug("Commit " + srcCommit.name() + " already merged into " + dstCommit + ", skip the merge");
return srcCommit;
}
} finally {
walk.close();
}
}
if (tryRebase(options)) {
LOG.debug("Run rebase, root " + gitRoot + ", revision " + srcCommit.name() + ", destination " + dstCommit.name());
try {
return rebase(gitRoot, db, srcCommit, dstCommit);
} catch (MergeFailedException e) {
if (enforceLinearHistory(options)) {
LOG.debug("Rebase failed, root " + gitRoot + ", revision " + srcCommit.name() + ", destination " + dstCommit.name(), e);
throw e;
}
} catch (IOException e) {
if (enforceLinearHistory(options)) {
LOG.debug("Rebase failed, root " + gitRoot + ", revision " + srcCommit.name() + ", destination " + dstCommit.name(), e);
throw e;
}
}
}
ResolveMerger merger = (ResolveMerger) MergeStrategy.RECURSIVE.newMerger(db, true);
boolean mergeSuccessful = merger.merge(dstCommit, srcCommit);
if (!mergeSuccessful) {
List<String> conflicts = merger.getUnmergedPaths();
Collections.sort(conflicts);
LOG.debug("Merge failed with conflicts, root " + gitRoot + ", revision " + srcCommit.name() + ", destination " + dstCommit.name() +
", conflicts " + conflicts);
throw new MergeFailedException(conflicts);
}
ObjectInserter inserter = db.newObjectInserter();
DirCache dc = DirCache.newInCore();
DirCacheBuilder dcb = dc.builder();
dcb.addTree(new byte[]{}, 0, db.getObjectDatabase().newReader(), merger.getResultTreeId());
inserter.flush();
dcb.finish();
ObjectId writtenTreeId = dc.writeTree(inserter);
CommitBuilder commitBuilder = new CommitBuilder();
final PersonIdent tagger = PersonIdentFactory.getTagger(gitRoot, db);
commitBuilder.setCommitter(tagger);
commitBuilder.setAuthor(tagger);
commitBuilder.setMessage(message);
commitBuilder.addParentId(dstCommit);
commitBuilder.addParentId(srcCommit);
commitBuilder.setTreeId(writtenTreeId);
ObjectId commitId = inserter.insert(commitBuilder);
inserter.flush();
return commitId;
}