private ObjectId rebase()

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