view mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerHgRepo.java @ 584:49b11c289395

Speed up subrepo changes collecting By default do not calculate file status in subrepo changes, report 'edited' in all the cases. Calculating file status is the most expensive mercurial operation. Also report only actually changed files in subrepo merge commits, otherwise they contain thousands of changed files from merged branches.
author Dmitry Neverov <dmitry.neverov@jetbrains.com>
date Tue, 09 Apr 2013 21:18:11 +0400
parents c3ec73ac68ca
children 6c480513e5c2
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 java.io.File;
import java.util.List;

/**
 * @author dmitry.neverov
 */
public class ServerHgRepo extends HgRepo {

  private final static HgVersion REVSET_HG_VERSION = new HgVersion(1, 7, 0);
  private final CommandSettingsFactory myCommandSettingsFactory;
  private final ServerPluginConfig myConfig;
  private File myLogTemplate;
  private File myLogNoFilesTemplate;
  private File myDagTemplate;
  private File myFastLogTemplate;
  private OperationContext myContext;

  public ServerHgRepo(@NotNull CommandSettingsFactory commandSettingsFactory,
                      @NotNull ServerPluginConfig config,
                      @NotNull File workingDir,
                      @NotNull String hgPath,
                      @NotNull AuthSettings authSettings) {
    super(commandSettingsFactory, workingDir, hgPath, authSettings);
    myCommandSettingsFactory = commandSettingsFactory;
    myConfig = config;
  }

  public void setOperationContext(@NotNull OperationContext context) {
    myContext = context;
  }

  public ServerHgRepo withLogTemplates(@NotNull File logTemplate,
                                       @NotNull File logNoFilesTemplate,
                                       @NotNull File dagTemplate,
                                       @NotNull File fastLogTemplate) {
    myLogTemplate = logTemplate;
    myLogNoFilesTemplate = logNoFilesTemplate;
    myDagTemplate = dagTemplate;
    myFastLogTemplate = fastLogTemplate;
    return this;
  }

  public LogCommand log() {
    return new LogCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir, myAuthSettings).withTemplate(myLogTemplate);
  }

  public LogCommand log(@NotNull HgVcsRoot root) {
    File template = root.isSubrepo() && !myConfig.reportSubrepoChangesFileStatus() ? myFastLogTemplate : myLogTemplate;
    return new LogCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir, myAuthSettings).withTemplate(template);
  }

  public MergeBaseCommand mergeBase() throws VcsException {
    HgVersion hgVersion = getHgVersion();
    if (hgVersion.isEqualsOrGreaterThan(REVSET_HG_VERSION))
      return new MergeBaseWithRevsets(this);
    else
      return new MergeBaseNoRevsets(this);
  }

  @NotNull
  public CollectChangesCommand collectChanges(@NotNull HgVcsRoot root) throws VcsException {
    if (myConfig.dontUseRevsets())
      return new CollectChangesNoRevsets(root, this, myLogNoFilesTemplate);

    HgVersion hgVersion = getHgVersion();
    if (hgVersion.isEqualsOrGreaterThan(REVSET_HG_VERSION)) {
      return new CollectChangesWithRevsets(root, this);
    } else {
      return new CollectChangesNoRevsets(root, this, myLogNoFilesTemplate);
    }
  }

  public boolean supportRevsets() throws VcsException {
    HgVersion hgVersion = getHgVersion();
    return hgVersion.isEqualsOrGreaterThan(REVSET_HG_VERSION);
  }

  private HgVersion getHgVersion() throws VcsException {
    if (myContext != null)
      return myContext.getHgVersion(this);
    return version().call();
  }

  @NotNull
  public DAG<String> loadDag() throws VcsException {
    LoadDagCommand loadDag = new LoadDagCommand(myCommandSettingsFactory.create(), myHgPath, myWorkingDir, myAuthSettings, myDagTemplate);
    loadDag.setMaxDagNodesCount(myConfig.getMaxDagNodesCount());
    List<Pair<String, String>> edges = loadDag.call();
    return DAGs.createFromEdges(edges);
  }
}