Run Git process for indexing with low priority

This commit is contained in:
Dmitry Jemerov
2018-05-16 16:19:17 +02:00
parent 48ade29f40
commit 61ae65c80b
11 changed files with 139 additions and 147 deletions
@@ -0,0 +1,41 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.execution.configurations
import com.intellij.openapi.util.SystemInfo
import com.intellij.openapi.util.registry.Registry
import java.io.File
/**
* @author yole
*/
fun setupLowPriorityExecution(commandLine: GeneralCommandLine, executablePath: String) {
if (!canRunLowPriority()) {
commandLine.exePath = executablePath
}
else {
if (SystemInfo.isWindows) {
// TODO
}
else {
commandLine.exePath = "/usr/bin/nice"
commandLine.addParameter("-n")
commandLine.addParameter("10")
commandLine.addParameter(executablePath)
}
}
}
private fun canRunLowPriority(): Boolean {
if (!Registry.`is`("ide.allow.low.priority.process")) {
return false
}
if (SystemInfo.isWindows) {
return false
}
else {
if (!niceExists) return false
}
return true
}
private val niceExists by lazy { File("/usr/bin/nice").exists() }
@@ -882,6 +882,8 @@ run.processes.with.pty=false
kill.windows.processes.softly=false
output.reader.blocking.mode=false
disable.winp=false
ide.allow.low.priority.process=true
ide.allow.low.priority.process.description=Allow running external processes with low priority when used for background operations
ide.certificate.manager=true
@@ -1,22 +1,9 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package git4idea.commands;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.LowPriorityProcessRunnerKt;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
@@ -56,6 +43,7 @@ public abstract class GitHandler {
private static final Logger TIME_LOG = Logger.getInstance("#time." + GitHandler.class.getName());
private final Project myProject;
@NotNull private final String myPathToExecutable;
private final GitCommand myCommand;
private boolean myPreValidateExecutable = true;
@@ -88,11 +76,27 @@ public abstract class GitHandler {
@NotNull File directory,
@NotNull GitCommand command,
@NotNull List<String> configParameters) {
this(project, directory, command, configParameters, false);
}
/**
* A constructor
* @param project a project
* @param directory a process directory
* @param command a command to execute
* @param lowPriorityProcess
*/
protected GitHandler(@NotNull Project project,
@NotNull File directory,
@NotNull GitCommand command,
@NotNull List<String> configParameters,
boolean lowPriorityProcess) {
this(project,
directory,
GitExecutableManager.getInstance().getPathToGit(project),
command,
configParameters);
configParameters,
lowPriorityProcess);
myProgressParameterAllowed =
GitVersionSpecialty.ABLE_TO_USE_PROGRESS_IN_REMOTE_COMMANDS.existsIn(project);
}
@@ -108,31 +112,55 @@ public abstract class GitHandler {
@NotNull VirtualFile vcsRoot,
@NotNull GitCommand command,
@NotNull List<String> configParameters) {
this(project, VfsUtil.virtualToIoFile(vcsRoot), command, configParameters);
this(project, vcsRoot, command, configParameters, false);
}
/**
* A constructor
* @param project a project
* @param vcsRoot a process directory
* @param command a command to execute
* @param lowPriorityProcess
*/
protected GitHandler(@NotNull Project project,
@NotNull VirtualFile vcsRoot,
@NotNull GitCommand command,
@NotNull List<String> configParameters,
boolean lowPriorityProcess) {
this(project, VfsUtil.virtualToIoFile(vcsRoot), command, configParameters, lowPriorityProcess);
}
/**
* A constructor for handler that can be run without project association
*
* @param project optional project
* @param project optional project
* @param directory working directory
* @param pathToExecutable path to git executable
* @param command git command to execute
* @param configParameters list of config parameters to use for this git execution
* @param lowPriorityProcess if true, the git process is started with low priority
*/
protected GitHandler(@Nullable Project project,
@NotNull File directory,
@NotNull String pathToExecutable,
@NotNull GitCommand command,
@NotNull List<String> configParameters) {
@NotNull List<String> configParameters,
boolean lowPriorityProcess) {
myProject = project;
myVcs = project != null ? GitVcs.getInstance(project) : null;
myPathToExecutable = pathToExecutable;
myCommand = command;
myCommandLine = new GeneralCommandLine()
.withWorkDirectory(directory)
.withExePath(pathToExecutable)
.withCharset(CharsetToolkit.UTF8_CHARSET);
if (lowPriorityProcess) {
LowPriorityProcessRunnerKt.setupLowPriorityExecution(myCommandLine, pathToExecutable);
}
else {
myCommandLine.setExePath(pathToExecutable);
}
for (String parameter : getConfigParameters(project, configParameters)) {
myCommandLine.addParameters("-c", parameter);
}
@@ -180,7 +208,7 @@ public abstract class GitHandler {
@NotNull
String getExecutablePath() {
return myCommandLine.getExePath();
return myPathToExecutable;
}
@NotNull
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package git4idea.commands;
import com.intellij.execution.ExecutionException;
@@ -70,7 +56,15 @@ public class GitLineHandler extends GitTextHandler {
@NotNull VirtualFile vcsRoot,
@NotNull GitCommand command,
@NotNull List<String> configParameters) {
super(project, vcsRoot, command, configParameters);
this(project, vcsRoot, command, configParameters, false);
}
public GitLineHandler(@NotNull Project project,
@NotNull VirtualFile vcsRoot,
@NotNull GitCommand command,
@NotNull List<String> configParameters,
boolean lowPriorityProcess) {
super(project, vcsRoot, command, configParameters, lowPriorityProcess);
}
public GitLineHandler(@Nullable Project project,
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package git4idea.commands;
import com.intellij.execution.ExecutionException;
@@ -57,7 +43,15 @@ public abstract class GitTextHandler extends GitHandler {
@NotNull VirtualFile vcsRoot,
@NotNull GitCommand command,
List<String> configParameters) {
super(project, vcsRoot, command, configParameters);
this(project, vcsRoot, command, configParameters, false);
}
protected GitTextHandler(@NotNull Project project,
@NotNull VirtualFile vcsRoot,
@NotNull GitCommand command,
List<String> configParameters,
boolean lowPriorityProcess) {
super(project, vcsRoot, command, configParameters, lowPriorityProcess);
}
public GitTextHandler(@Nullable Project project,
@@ -65,7 +59,7 @@ public abstract class GitTextHandler extends GitHandler {
@NotNull String pathToExecutable,
@NotNull GitCommand command,
@NotNull List<String> configParameters) {
super(project, directory, pathToExecutable, command, configParameters);
super(project, directory, pathToExecutable, command, configParameters, false);
}
@Nullable
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package git4idea.history;
import com.intellij.openapi.project.Project;
@@ -260,7 +246,7 @@ public class GitHistoryUtils {
@NotNull VirtualFile root,
@NotNull Consumer<? super GitCommit> commitConsumer,
@NotNull String... parameters) throws VcsException {
GitLogUtil.readFullDetails(project, root, commitConsumer, true, true, parameters);
GitLogUtil.readFullDetails(project, root, commitConsumer, true, true, false, parameters);
}
public static long getAuthorTime(@NotNull Project project, @NotNull FilePath path, @NotNull String commitsId) throws VcsException {
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package git4idea.history;
import com.intellij.openapi.application.ReadAction;
@@ -109,7 +95,7 @@ public class GitLogUtil {
return;
}
GitLineHandler handler = createGitHandler(project, root);
GitLineHandler handler = createGitHandler(project, root, Collections.emptyList(), true);
GitLogParser parser = new GitLogParser(project, GitLogParser.NameStatus.NONE, HASH, PARENTS, COMMIT_TIME,
AUTHOR_NAME, AUTHOR_EMAIL, REF_NAMES);
handler.setStdoutSuppressed(true);
@@ -149,6 +135,7 @@ public class GitLogUtil {
@NotNull
public static VcsLogProvider.DetailedLogData collectMetadata(@NotNull Project project,
@NotNull VirtualFile root,
boolean lowPriorityProcess,
String... params) throws VcsException {
VcsLogObjectsFactory factory = getObjectsFactoryWithDisposeCheck(project);
if (factory == null) {
@@ -156,7 +143,7 @@ public class GitLogUtil {
}
Set<VcsRef> refs = new OpenTHashSet<>(GitLogProvider.DONT_CONSIDER_SHA);
List<VcsCommitMetadata> commits =
collectMetadata(project, root, record -> {
collectMetadata(project, root, lowPriorityProcess, record -> {
GitCommit commit = createCommit(project, root, Collections.singletonList(record), factory);
Collection<VcsRef> refsInRecord = parseRefs(record.getRefs(), commit.getId(), factory, root);
for (VcsRef ref : refsInRecord) {
@@ -173,13 +160,14 @@ public class GitLogUtil {
@NotNull
private static List<VcsCommitMetadata> collectMetadata(@NotNull Project project,
@NotNull VirtualFile root,
boolean lowPriorityProcess,
@NotNull NullableFunction<GitLogRecord, VcsCommitMetadata> converter,
String... parameters) throws VcsException {
List<VcsCommitMetadata> commits = ContainerUtil.newArrayList();
try {
GitLineHandler handler = createGitHandler(project, root, createConfigParameters(false, false, DiffRenameLimit.GIT_CONFIG));
GitLineHandler handler = createGitHandler(project, root, createConfigParameters(false, false, DiffRenameLimit.GIT_CONFIG), lowPriorityProcess);
readRecordsFromHandler(project, root, true, false, record -> commits.add(converter.fun(record)), handler, parameters);
}
catch (VcsException e) {
@@ -232,7 +220,7 @@ public class GitLogUtil {
List<GitCommit> commits = ContainerUtil.newArrayList();
try {
readFullDetails(project, root, commits::add, true, true, parameters);
readFullDetails(project, root, commits::add, true, true, false, parameters);
}
catch (VcsException e) {
if (commits.isEmpty()) {
@@ -248,10 +236,10 @@ public class GitLogUtil {
@NotNull Consumer<? super GitCommit> commitConsumer,
boolean includeRootChanges,
boolean preserverOrder,
@NotNull String... parameters) throws VcsException {
boolean lowPriorityProcess, @NotNull String... parameters) throws VcsException {
DiffRenameLimit renameLimit = DiffRenameLimit.REGISTRY;
GitLineHandler handler = createGitHandler(project, root, createConfigParameters(true, includeRootChanges, renameLimit));
GitLineHandler handler = createGitHandler(project, root, createConfigParameters(true, includeRootChanges, renameLimit), lowPriorityProcess);
readFullDetailsFromHandler(project, root, commitConsumer, renameLimit, handler, preserverOrder, parameters);
}
@@ -343,7 +331,7 @@ public class GitLogUtil {
@NotNull List<String> hashes,
boolean includeRootChanges,
@NotNull DiffRenameLimit renameLimit) throws VcsException {
GitLineHandler handler = createGitHandler(project, root, createConfigParameters(true, includeRootChanges, renameLimit));
GitLineHandler handler = createGitHandler(project, root, createConfigParameters(true, includeRootChanges, renameLimit), true);
sendHashesToStdin(vcs, hashes, handler);
readFullDetailsFromHandler(project, root, commitConsumer, renameLimit, handler, false, getNoWalkParameter(vcs), STDIN);
@@ -366,14 +354,15 @@ public class GitLogUtil {
@NotNull
public static GitLineHandler createGitHandler(@NotNull Project project, @NotNull VirtualFile root) {
return createGitHandler(project, root, Collections.emptyList());
return createGitHandler(project, root, Collections.emptyList(), false);
}
@NotNull
private static GitLineHandler createGitHandler(@NotNull Project project,
@NotNull VirtualFile root,
@NotNull List<String> configParameters) {
GitLineHandler handler = new GitLineHandler(project, root, GitCommand.LOG, configParameters);
@NotNull List<String> configParameters,
boolean lowPriorityProcess) {
GitLineHandler handler = new GitLineHandler(project, root, GitCommand.LOG, configParameters, lowPriorityProcess);
handler.setWithMediator(false);
return handler;
}
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package git4idea.log;
import com.intellij.openapi.Disposable;
@@ -107,7 +93,7 @@ public class GitLogProvider implements VcsLogProvider {
boolean refresh = requirements instanceof VcsLogProviderRequirementsEx && ((VcsLogProviderRequirementsEx)requirements).isRefresh();
DetailedLogData data = GitLogUtil.collectMetadata(myProject, root, params);
DetailedLogData data = GitLogUtil.collectMetadata(myProject, root, true, params);
Set<VcsRef> safeRefs = data.getRefs();
Set<VcsRef> allRefs = new OpenTHashSet<>(safeRefs, DONT_CONSIDER_SHA);
@@ -296,7 +282,7 @@ public class GitLogProvider implements VcsLogProvider {
Set<VcsCommitMetadata> commits = ContainerUtil.newHashSet();
VcsFileUtil.foreachChunk(new ArrayList<>(unmatchedTags), 1, tagsChunk -> {
String[] parameters = ArrayUtil.toStringArray(ContainerUtil.concat(params, tagsChunk));
DetailedLogData logData = GitLogUtil.collectMetadata(myProject, root, parameters);
DetailedLogData logData = GitLogUtil.collectMetadata(myProject, root, true, parameters);
refs.addAll(logData.getRefs());
commits.addAll(logData.getCommits());
});
@@ -330,7 +316,7 @@ public class GitLogProvider implements VcsLogProvider {
}
GitLogUtil.readFullDetails(myProject, root, commitConsumer, shouldIncludeRootChanges(root),
false, ArrayUtil.toStringArray(GitLogUtil.LOG_ALL));
false, true, ArrayUtil.toStringArray(GitLogUtil.LOG_ALL));
}
@Override
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package git4idea.rebase
import com.intellij.notification.NotificationAction
@@ -163,7 +149,7 @@ class GitRewordOperation(private val repository: GitRepository,
private fun findNewHashOfRewordedCommit(newHead: String): Hash? {
val newCommitsRange = "${commit.parents.first().asString()}..$newHead"
val newCommits = GitLogUtil.collectMetadata(project, repository.root, newCommitsRange).commits
val newCommits = GitLogUtil.collectMetadata(project, repository.root, false, newCommitsRange).commits
if (newCommits.isEmpty()) {
LOG.error("Couldn't find commits after reword in range $newCommitsRange")
return null
@@ -25,7 +25,7 @@ class GitLogUtilTest : GitSingleRepoTest() {
touch("file.txt", "content")
repo.addCommit(message)
GitLogUtil.readFullDetails(myProject, repo.root, CollectConsumer(details), true, true)
GitLogUtil.readFullDetails(myProject, repo.root, CollectConsumer(details), true, true, true)
val lastCommit = ContainerUtil.getFirstItem(details)
assertNotNull(lastCommit)
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package git4idea.test
import com.intellij.openapi.application.ApplicationManager
@@ -64,7 +50,7 @@ fun GitRepository.assertLatestSubjects(vararg expectedMessages: String) {
}
private fun GitRepository.assertLatestHistory(mapping: (VcsCommitMetadata) -> String, vararg expectedMessages: String) {
val actualMessages = GitLogUtil.collectMetadata(project, root).commits
val actualMessages = GitLogUtil.collectMetadata(project, root, false).commits
.map(mapping)
.subList(0, expectedMessages.size)
assertOrderedEquals("History is incorrect", actualMessages, expectedMessages.asList())