git: display affected roots in error messages

GitOrigin-RevId: 48952aa80178bc0e59fa9554fb16744a567283fb
This commit is contained in:
Aleksey Pivovarov
2023-10-19 13:31:11 +02:00
committed by intellij-monorepo-bot
parent e32fa25fa4
commit 9a4c97f26e
7 changed files with 82 additions and 21 deletions

View File

@@ -13,6 +13,7 @@ import git4idea.i18n.GitBundle;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collection;
@@ -31,24 +32,35 @@ public class GitCommandResult {
private final boolean myAuthenticationFailed;
private final List<String> myErrorOutput;
private final List<String> myOutput;
protected final @Nullable @Nls String myRootName;
public GitCommandResult(boolean startFailed,
int exitCode,
@NotNull List<String> errorOutput,
@NotNull List<String> output) {
this(startFailed, exitCode, false, errorOutput, output);
this(startFailed, exitCode, errorOutput, output, null);
}
public GitCommandResult(boolean startFailed,
int exitCode,
@NotNull List<String> errorOutput,
@NotNull List<String> output,
@Nullable @Nls String rootName) {
this(startFailed, exitCode, false, errorOutput, output, rootName);
}
private GitCommandResult(boolean startFailed,
int exitCode,
boolean authenticationFailed,
@NotNull List<String> errorOutput,
@NotNull List<String> output) {
@NotNull List<String> output,
@Nullable @Nls String rootName) {
myExitCode = exitCode;
myStartFailed = startFailed;
myAuthenticationFailed = authenticationFailed;
myErrorOutput = errorOutput;
myOutput = output;
myRootName = rootName;
}
/**
@@ -59,7 +71,8 @@ public class GitCommandResult {
result.myExitCode,
authenticationFailed,
result.myErrorOutput,
result.myOutput);
result.myOutput,
result.myRootName);
}
/**
@@ -139,15 +152,20 @@ public class GitCommandResult {
* @throws VcsException with message from {@link #getErrorOutputAsJoinedString()}
*/
public void throwOnError(int... ignoredErrorCodes) throws VcsException {
if (!success(ignoredErrorCodes)) throw new VcsException(getErrorOutputAsJoinedString());
if (success(ignoredErrorCodes)) return;
String errorMessage = getErrorOutputAsJoinedString();
if (myRootName != null) {
errorMessage = "[" + myRootName + "] " + errorMessage;
}
throw new VcsException(errorMessage);
}
static @NotNull GitCommandResult startError(@NotNull @Nls String error) {
return new GitCommandResult(true, -1, Collections.singletonList(error), Collections.emptyList());
return new GitCommandResult(true, -1, Collections.singletonList(error), Collections.emptyList(), null);
}
public static @NotNull GitCommandResult error(@NotNull @Nls String error) {
return new GitCommandResult(false, 1, Collections.singletonList(error), Collections.emptyList());
return new GitCommandResult(false, 1, Collections.singletonList(error), Collections.emptyList(), null);
}
/**

View File

@@ -25,7 +25,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.EnvironmentUtil;
import com.intellij.util.EventDispatcher;
import com.intellij.util.ThrowableConsumer;
import com.intellij.vcs.VcsLocaleHelper;
import com.intellij.vcsUtil.VcsFileUtil;
import git4idea.GitVcs;
import git4idea.config.GitExecutable;
@@ -486,8 +485,7 @@ public abstract class GitHandler {
executionEnvironment.putAll(myCustomEnv);
executionEnvironment.put(GitCommand.IJ_HANDLER_MARKER_ENV, "true");
// customizers take read locks, which could not be acquired under potemkin progress
if (!(ProgressManager.getInstance().getProgressIndicator() instanceof PotemkinProgress)) {
if (!shouldSuppressReadLocks()) {
VcsEnvCustomizer.EP_NAME.forEachExtensionSafe(customizer -> {
customizer.customizeCommandAndEnvironment(myProject, executionEnvironment, myExecutableContext);
});
@@ -496,6 +494,16 @@ public abstract class GitHandler {
}
}
/**
* Tasks executed under {@link PotemkinProgress#runInBackground} cannot take read lock.
*/
protected static boolean shouldSuppressReadLocks() {
if (ProgressManager.getInstance().getProgressIndicator() instanceof PotemkinProgress) {
return !ApplicationManager.getApplication().isDispatchThread();
}
return false;
}
protected abstract Process startProcess() throws ExecutionException;
/**

View File

@@ -17,6 +17,7 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread;
@@ -32,6 +33,7 @@ import git4idea.rebase.GitSimpleEditorHandler;
import git4idea.rebase.GitUnstructuredEditor;
import git4idea.util.GitVcsConsoleWriter;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -197,10 +199,35 @@ public abstract class GitImplBase implements Git {
catch (IOException e) {
return GitCommandResult.error(GitBundle.message("git.error.cant.process.output", e.getLocalizedMessage()));
}
String rootName = getPresentableRootName(handler);
return new GitCommandResult(resultListener.myStartFailed,
resultListener.myExitCode,
outputCollector.myErrorOutput,
outputCollector.myOutput);
outputCollector.myOutput,
rootName);
}
private static @Nullable @Nls String getPresentableRootName(@NotNull GitLineHandler handler) {
if (GitHandler.shouldSuppressReadLocks()) return null;
if (handler.getCommand().equals(GitCommand.VERSION)) return null;
VirtualFile root = handler.getExecutableContext().getRoot();
if (root == null) return null;
Project project = handler.project();
if (project == null) return root.getName();
ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project);
VirtualFile vcsRoot = vcsManager.getVcsRootFor(root);
if (root.equals(vcsRoot)) {
if (vcsManager.getRootsUnderVcs(GitVcs.getInstance(project)).length == 1) {
return null;
}
return ProjectLevelVcsManager.getInstance(project).getShortNameForVcsRoot(root);
}
return root.getName();
}
/**

View File

@@ -3,16 +3,24 @@ package git4idea.commands
import git4idea.commands.GitRebaseCommandResult.CancelState.*
class GitRebaseCommandResult private constructor(val commandResult: GitCommandResult,
private val cancelState: CancelState) : GitCommandResult(commandResult.hasStartFailed(),
commandResult.exitCode,
commandResult.output,
commandResult.errorOutput) {
class GitRebaseCommandResult private constructor(
val commandResult: GitCommandResult,
private val cancelState: CancelState
) : GitCommandResult(commandResult.hasStartFailed(),
commandResult.exitCode,
commandResult.output,
commandResult.errorOutput,
commandResult.myRootName) {
companion object {
@JvmStatic fun normal(commandResult: GitCommandResult) = GitRebaseCommandResult(commandResult, NOT_CANCELLED)
@JvmStatic fun cancelledInCommitList(commandResult: GitCommandResult) = GitRebaseCommandResult(commandResult, COMMIT_LIST_CANCELLED)
@JvmStatic fun cancelledInCommitMessage(commandResult: GitCommandResult) = GitRebaseCommandResult(commandResult, EDITOR_CANCELLED)
@JvmStatic
fun normal(commandResult: GitCommandResult) = GitRebaseCommandResult(commandResult, NOT_CANCELLED)
@JvmStatic
fun cancelledInCommitList(commandResult: GitCommandResult) = GitRebaseCommandResult(commandResult, COMMIT_LIST_CANCELLED)
@JvmStatic
fun cancelledInCommitMessage(commandResult: GitCommandResult) = GitRebaseCommandResult(commandResult, EDITOR_CANCELLED)
}
private enum class CancelState {

View File

@@ -645,7 +645,7 @@ class GitBranchWorkerTest : GitPlatformTest() {
repository.git("branch todelete")
}
git.onBranchDelete {
if (second == it) GitCommandResult(false, 1, listOf("Couldn't remove branch"), listOf())
if (second == it) GitCommandResult.error("Couldn't remove branch")
else null
}
}

View File

@@ -55,7 +55,7 @@ class GitPushOperationMultiRepoTest : GitPushOperationBaseTest() {
fun `test try push from all roots even if one fails`() {
// fail in the first repo
git.onPush {
if (it == ultimate) GitCommandResult(false, 128, listOf("Failed to push to origin"), listOf<String>())
if (it == ultimate) GitCommandResult.error("Failed to push to origin")
else null
}

View File

@@ -166,7 +166,7 @@ class TestGitImpl : GitImpl() {
}
}
private fun fatalResult() = GitCommandResult(false, 128, listOf("fatal: error: $UNKNOWN_ERROR_TEXT"), emptyList<String>())
private fun fatalResult() = GitCommandResult(false, 128, listOf("fatal: error: $UNKNOWN_ERROR_TEXT"), emptyList<String>(), null)
}