Mercurial > hg > mercurial
changeset 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.
line wrap: on
line diff
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/HgVcsRoot.java Mon Apr 08 13:06:17 2013 +0400 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/HgVcsRoot.java Tue Apr 09 21:18:11 2013 +0400 @@ -126,6 +126,10 @@ return myDetectSubrepoChanges; } + public boolean isSubrepo() { + return Boolean.valueOf(getProperty("teamcity.internal.subrepo")); + } + public String getVcsName() { return myRoot.getVcsName();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-server/resources/buildServerResources/fastlog.template Tue Apr 09 21:18:11 2013 +0400 @@ -0,0 +1,8 @@ +header = '<?xml version="1.0"?>\n<log>\n' +footer = '</log>\n' + +changeset = '<logentry revision="{rev}" shortnode="{node|short}">\n{parents}<author original="{author|xmlescape}"/>\n<date>{date|date|xmlescape}</date>\n<msg xml:space="preserve">{desc|xmlescape}</msg>\n<paths>\n{files}</paths>\n</logentry>\n' + +file = '<path action="M">{file|xmlescape}</path>\n' + +parent = '<parent revision="{rev}" shortnode="{node|short}"/>\n'
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/RepoFactory.java Mon Apr 08 13:06:17 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/RepoFactory.java Tue Apr 09 21:18:11 2013 +0400 @@ -19,17 +19,15 @@ private final ServerPluginConfig myConfig; private final CommandSettingsFactory myCommandSettingsFactory; - private File myLogTemplate; - private File myLogNoFilesTemplate; - private File myDagTemplate; - public RepoFactory(@NotNull ServerPluginConfig config, - @NotNull CommandSettingsFactory commandSettingsFactory) throws IOException { + private final MercurialLogTemplate myLogTemplate = new MercurialLogTemplate("/buildServerResources/log.template", "hg.log.template"); + private final MercurialLogTemplate myLogNoFilesTemplate = new MercurialLogTemplate("/buildServerResources/log.no.files.template", "hg.short.log.template"); + private final MercurialLogTemplate myDagTemplate = new MercurialLogTemplate("/buildServerResources/dag.template", "hg.dag.template"); + private final MercurialLogTemplate myFastLogTemplate = new MercurialLogTemplate("/buildServerResources/fastlog.template", "hg.fastlog.template"); + + public RepoFactory(@NotNull ServerPluginConfig config, @NotNull CommandSettingsFactory commandSettingsFactory) throws IOException { myConfig = config; myCommandSettingsFactory = commandSettingsFactory; - myLogTemplate = createLogTemplate(); - myLogNoFilesTemplate = createLogNoFilesTemplate(); - myDagTemplate = createDagTemplate(); } @NotNull @@ -37,61 +35,50 @@ @NotNull String hgPath, @NotNull AuthSettings authSettings) throws VcsException { return new ServerHgRepo(myCommandSettingsFactory, myConfig, workingDir, hgPath, authSettings) - .withLogTemplates(getTemplate(), getLogNoFilesTemplate(), getDagTemplate()); + .withLogTemplates(myLogTemplate.getTemplate(), + myLogNoFilesTemplate.getTemplate(), + myDagTemplate.getTemplate(), + myFastLogTemplate.getTemplate()); } public void dispose() { - delete(myLogTemplate); - } - - private File getTemplate() throws VcsException { - if (myLogTemplate.isFile() && myLogTemplate.exists()) - return myLogTemplate; - try { - myLogTemplate = createLogTemplate(); - return myLogTemplate; - } catch (IOException e) { - throw new VcsException("Cannot create mercurial log template", e); - } - } - - private File getLogNoFilesTemplate() throws VcsException { - if (myLogNoFilesTemplate.isFile() && myLogNoFilesTemplate.exists()) - return myLogNoFilesTemplate; - try { - myLogNoFilesTemplate = createLogNoFilesTemplate(); - return myLogNoFilesTemplate; - } catch (IOException e) { - throw new VcsException("Cannot create mercurial log template", e); - } + myLogTemplate.dispose(); + myLogNoFilesTemplate.dispose(); + myDagTemplate.dispose(); + myFastLogTemplate.dispose(); } - private File getDagTemplate() throws VcsException { - if (myDagTemplate.isFile() && myDagTemplate.exists()) - return myDagTemplate; - try { - myDagTemplate = createLogNoFilesTemplate(); - return myDagTemplate; - } catch (IOException e) { - throw new VcsException("Cannot create mercurial log template", e); + private static class MercurialLogTemplate { + private final String myResourcePath; + private final String myTmpFileSuffix; + private File myFile; + + private MercurialLogTemplate(@NotNull String resourcePath, @NotNull String tmpFileSuffix) throws IOException { + myResourcePath = resourcePath; + myTmpFileSuffix = tmpFileSuffix; + copyTemplate(); + } + + @NotNull + public File getTemplate() throws VcsException { + if (myFile.isFile() && myFile.exists()) + return myFile; + try { + copyTemplate(); + return myFile; + } catch (IOException e) { + throw new VcsException("Cannot create mercurial log template", e); + } + } + + public void dispose() { + delete(myFile); + } + + private void copyTemplate() throws IOException { + File template = createTempFile("teamcity", myTmpFileSuffix); + FileUtil.copyResource(RepoFactory.class, myResourcePath, template); + myFile = template; } } - - private File createLogTemplate() throws IOException { - return createTmpTemplateFile("hg.log.template", "/buildServerResources/log.template"); - } - - private File createLogNoFilesTemplate() throws IOException { - return createTmpTemplateFile("hg.short.log.template", "/buildServerResources/log.no.files.template"); - } - - private File createDagTemplate() throws IOException { - return createTmpTemplateFile("hg.dag.template", "/buildServerResources/dag.template"); - } - - private File createTmpTemplateFile(@NotNull String tmpFileSuffix, @NotNull String resourcePath) throws IOException { - File template = createTempFile("teamcity", tmpFileSuffix); - FileUtil.copyResource(RepoFactory.class, resourcePath, template); - return template; - } }
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerHgRepo.java Mon Apr 08 13:06:17 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerHgRepo.java Tue Apr 09 21:18:11 2013 +0400 @@ -21,6 +21,7 @@ private File myLogTemplate; private File myLogNoFilesTemplate; private File myDagTemplate; + private File myFastLogTemplate; private OperationContext myContext; public ServerHgRepo(@NotNull CommandSettingsFactory commandSettingsFactory, @@ -39,10 +40,12 @@ public ServerHgRepo withLogTemplates(@NotNull File logTemplate, @NotNull File logNoFilesTemplate, - @NotNull File dagTemplate) { + @NotNull File dagTemplate, + @NotNull File fastLogTemplate) { myLogTemplate = logTemplate; myLogNoFilesTemplate = logNoFilesTemplate; myDagTemplate = dagTemplate; + myFastLogTemplate = fastLogTemplate; return this; } @@ -50,6 +53,11 @@ 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)) @@ -61,13 +69,13 @@ @NotNull public CollectChangesCommand collectChanges(@NotNull HgVcsRoot root) throws VcsException { if (myConfig.dontUseRevsets()) - return new CollectChangesNoRevsets(this, myLogNoFilesTemplate); + return new CollectChangesNoRevsets(root, this, myLogNoFilesTemplate); HgVersion hgVersion = getHgVersion(); if (hgVersion.isEqualsOrGreaterThan(REVSET_HG_VERSION)) { - return new CollectChangesWithRevsets(this); + return new CollectChangesWithRevsets(root, this); } else { - return new CollectChangesNoRevsets(this, myLogNoFilesTemplate); + return new CollectChangesNoRevsets(root, this, myLogNoFilesTemplate); } }
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfig.java Mon Apr 08 13:06:17 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfig.java Tue Apr 09 21:18:11 2013 +0400 @@ -31,4 +31,6 @@ @Nullable public CronExpression getCleanupCronExpression(); + + public boolean reportSubrepoChangesFileStatus(); }
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigImpl.java Mon Apr 08 13:06:17 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigImpl.java Tue Apr 09 21:18:11 2013 +0400 @@ -84,4 +84,8 @@ return null; } } + + public boolean reportSubrepoChangesFileStatus() { + return TeamCityProperties.getBoolean("teamcity.hg.reportSubrepoChangesFileStatus"); + } }
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CollectChangesNoRevsets.java Mon Apr 08 13:06:17 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CollectChangesNoRevsets.java Tue Apr 09 21:18:11 2013 +0400 @@ -16,10 +16,12 @@ */ public class CollectChangesNoRevsets extends CollectChangesCommand { - private ServerHgRepo myRepo; - private File myLogNoFilesTemplate; + private final HgVcsRoot myRoot; + private final ServerHgRepo myRepo; + private final File myLogNoFilesTemplate; - public CollectChangesNoRevsets(@NotNull ServerHgRepo repo, @NotNull File logNoFilesTemplate) { + public CollectChangesNoRevsets(@NotNull HgVcsRoot root, @NotNull ServerHgRepo repo, @NotNull File logNoFilesTemplate) { + myRoot = root; myRepo = repo; myLogNoFilesTemplate = logNoFilesTemplate; } @@ -117,7 +119,7 @@ private List<ChangeSet> getAllHistoryUpTo(@NotNull final String revision) throws VcsException { - return myRepo.log() + return myRepo.log(myRoot) .fromRevision(revision) .toRevision("0") .showCommitsFromAllBranches() @@ -127,7 +129,7 @@ private List<ChangeSet> getRevisionsBetween(@NotNull String fromCommit, @NotNull String toCommit) throws VcsException { - return myRepo.log() + return myRepo.log(myRoot) .fromRevision(toCommit) .toRevision(fromCommit) .showCommitsFromAllBranches() @@ -135,7 +137,7 @@ } private List<ChangeSet> getRevisionsBetween(int fromRevNum, @NotNull String toCommit) throws VcsException { - return myRepo.log() + return myRepo.log(myRoot) .fromRevision(toCommit) .toRevision(String.valueOf(fromRevNum)) .showCommitsFromAllBranches()
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CollectChangesWithRevsets.java Mon Apr 08 13:06:17 2013 +0400 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CollectChangesWithRevsets.java Tue Apr 09 21:18:11 2013 +0400 @@ -1,6 +1,7 @@ package jetbrains.buildServer.buildTriggers.vcs.mercurial.command; import jetbrains.buildServer.buildTriggers.vcs.mercurial.HgRepo; +import jetbrains.buildServer.buildTriggers.vcs.mercurial.ServerHgRepo; import jetbrains.buildServer.vcs.VcsException; import org.jetbrains.annotations.NotNull; @@ -11,9 +12,11 @@ */ public class CollectChangesWithRevsets extends CollectChangesCommand { - private HgRepo myRepo; + private final HgVcsRoot myRoot; + private final ServerHgRepo myRepo; - public CollectChangesWithRevsets(@NotNull HgRepo repo) { + public CollectChangesWithRevsets(@NotNull HgVcsRoot root, @NotNull ServerHgRepo repo) { + myRoot = root; myRepo = repo; } @@ -34,7 +37,7 @@ revsets.append(" + ").append(from); } } - return myRepo.log() + return myRepo.log(myRoot) .showCommitsFromAllBranches() .withRevsets(revsets.toString()) .call();
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigBuilder.java Mon Apr 08 13:06:17 2013 +0400 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerPluginConfigBuilder.java Tue Apr 09 21:18:11 2013 +0400 @@ -69,6 +69,10 @@ public CronExpression getCleanupCronExpression() { return null; } + + public boolean reportSubrepoChangesFileStatus() { + return false; + } }; }