view mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MergeBaseNoRevsets.java @ 299:e9e7d9fcf57d

Use customized xml output from the 'hg log' command instead of running 'hg status' for every commit
author Dmitry Neverov <dmitry.neverov@jetbrains.com>
date Thu, 08 Sep 2011 12:56:56 +0400
parents 8c10f5cec37d
children e0464f11206c
line wrap: on
line source
package jetbrains.buildServer.buildTriggers.vcs.mercurial;

import com.intellij.openapi.util.Pair;
import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.*;
import jetbrains.buildServer.util.graph.DAG;
import jetbrains.buildServer.util.graph.DAGs;
import jetbrains.buildServer.vcs.VcsException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.util.*;

/**
 * Implementation of merge-base for hg versions which don't have revsets
 * @author dmitry.neverov
 */
public final class MergeBaseNoRevsets implements MergeBaseCommand {

  private final Settings mySettings;
  private final File myWorkingDir;
  private final CommandFactory myCommandFactory;

  public MergeBaseNoRevsets(@NotNull final Settings settings, @NotNull final File workingDir, @NotNull final CommandFactory commandFactory) {
    mySettings = settings;
    myWorkingDir = workingDir;
    myCommandFactory = commandFactory;
  }


  @Nullable
  public String execute(@NotNull final String revision1, @NotNull final String revision2) {
    if (revision1.equals(revision2))
      return revision1;
    try {
      List<Pair<String, String>> edges = new ArrayList<Pair<String, String>>();
      fillEdges(edges, getRevisionsReachableFrom(revision1));
      fillEdges(edges, getRevisionsReachableFrom(revision2));
      DAG<String> dag = DAGs.createFromEdges(edges);
      List<String> commonAncestors = dag.getCommonAncestors(new ChangeSetRevision(revision1).getId(), new ChangeSetRevision(revision2).getId());
      return commonAncestors.isEmpty() ? null : commonAncestors.get(0);
    } catch (VcsException e) {
      return null;
    }
  }


  private List<ChangeSet> getRevisionsReachableFrom(@NotNull final String revision) throws VcsException {
    LogCommand log = myCommandFactory.createLog(mySettings, myWorkingDir);
    log.setFromRevId(new ChangeSetRevision(revision).getId());
    log.showCommitsFromAllBranches();
    log.setToRevId("0");
    return log.execute();
  }


  private void fillEdges(List<Pair<String, String>> edges, List<ChangeSet> csets) {
    for (ChangeSet cset : csets) {
      for (ChangeSetRevision parent : cset.getParents()) {
        edges.add(Pair.create(cset.getId(), parent.getId()));
      }
    }
  }
}