in git-server/src/main/java/jetbrains/buildServer/buildTriggers/vcs/git/GitMergeSupport.java [243:304]
private ObjectId rebase(@NotNull GitVcsRoot gitRoot,
@NotNull Repository db,
@NotNull RevCommit srcCommit,
@NotNull RevCommit dstCommit) throws IOException, MergeFailedException {
RevWalk walk = new RevWalk(db);
try {
RevCommit src = walk.parseCommit(srcCommit);
RevCommit dst = walk.parseCommit(dstCommit);
walk.markStart(src);
walk.markStart(dst);
walk.setRevFilter(RevFilter.MERGE_BASE);
RevCommit base = walk.next();
Map<ObjectId, RevCommit> tree2commit = new HashMap<ObjectId, RevCommit>();
RevCommit c;
if (base != null) {
walk.reset();
walk.setRevFilter(RevFilter.ALL);
walk.markStart(dst);
walk.markUninteresting(base);
while ((c = walk.next()) != null) {
tree2commit.put(c.getTree().getId(), c);
}
}
walk.reset();
walk.markStart(src);
walk.markUninteresting(dst);
walk.sort(RevSort.TOPO);
walk.sort(RevSort.REVERSE);
Map<RevCommit, RevCommit> orig2rebased = new HashMap<RevCommit, RevCommit>();
List<RevCommit> toRebase = new ArrayList<RevCommit>();
while ((c = walk.next()) != null) {
ObjectId treeId = c.getTree().getId();
RevCommit existing = tree2commit.get(treeId);
if (existing != null) {
orig2rebased.put(c, existing);
} else {
if (c.getParentCount() > 1) {
throw new MergeFailedException(asList("Rebase of merge commits is not supported"));
} else {
toRebase.add(c);
}
}
}
orig2rebased.put(toRebase.get(0).getParent(0), dstCommit);
ObjectInserter inserter = db.newObjectInserter();
for (RevCommit commit : toRebase) {
RevCommit p = commit.getParent(0);
RevCommit b = orig2rebased.get(p);
ObjectId rebased = rebaseCommit(gitRoot, db, inserter, commit, b);
orig2rebased.put(commit, walk.parseCommit(rebased));
}
return orig2rebased.get(toRebase.get(toRebase.size() - 1));
} finally {
walk.close();
}
}