diff --git a/plugins/git4idea/src/git4idea/GitOperationsCollector.kt b/plugins/git4idea/src/git4idea/GitOperationsCollector.kt index e961bfcf89c2..2abd31566f66 100644 --- a/plugins/git4idea/src/git4idea/GitOperationsCollector.kt +++ b/plugins/git4idea/src/git4idea/GitOperationsCollector.kt @@ -10,6 +10,7 @@ import com.intellij.openapi.project.Project import git4idea.actions.workingTree.GitWorkingTreeDialogData import git4idea.branch.GitRebaseParams import git4idea.commands.GitCommandResult +import git4idea.config.GitIncomingRemoteCheckStrategy import git4idea.inMemory.rebase.InMemoryRebaseResult import git4idea.merge.GitMergeOption import git4idea.pull.GitPullOption @@ -23,7 +24,7 @@ import git4idea.repo.GitRepository internal object GitOperationsCollector : CounterUsagesCollector() { override fun getGroup(): EventLogGroup = GROUP - private val GROUP: EventLogGroup = EventLogGroup(id = "git.operations", version = 10) + private val GROUP: EventLogGroup = EventLogGroup(id = "git.operations", version = 11) internal val UPDATE_FORCE_PUSHED_BRANCH_ACTIVITY = GROUP.registerIdeActivity("update.force.pushed") @@ -312,5 +313,18 @@ internal object GitOperationsCollector : CounterUsagesCollector() { val trackedBranch = repository.getBranchTrackInfo(currentBranch.name)?.remoteBranch ?: return false return trackedBranch == selectedBranch } - //endregion + + internal val REMOTE_CHECK_STRATEGY = EventFields.Enum("remoteCheckStrategy") + private val REMOTE_INFO_SUCCESS = EventFields.Boolean("success") + private val REMOTE_INFO_REQUEST_EVENT = GROUP.registerVarargEvent( + "remote.info.request", + "Remote state requested in background", + REMOTE_CHECK_STRATEGY, + REMOTE_INFO_SUCCESS, + ) + + @JvmStatic + fun logRemoteInfoRequest(project: Project, strategy: GitIncomingRemoteCheckStrategy, success: Boolean) { + REMOTE_INFO_REQUEST_EVENT.log(project, REMOTE_CHECK_STRATEGY.with(strategy), REMOTE_INFO_SUCCESS.with(success)) + } } diff --git a/plugins/git4idea/src/git4idea/GitStatisticsCollector.kt b/plugins/git4idea/src/git4idea/GitStatisticsCollector.kt index fe171882d9b8..3e881f57f69f 100644 --- a/plugins/git4idea/src/git4idea/GitStatisticsCollector.kt +++ b/plugins/git4idea/src/git4idea/GitStatisticsCollector.kt @@ -29,12 +29,14 @@ import com.intellij.vcs.log.impl.VcsLogUiProperties import com.intellij.vcs.log.impl.VcsProjectLog import com.intellij.vcs.log.ui.MainVcsLogUi import com.intellij.vcsUtil.VcsUtil +import git4idea.GitOperationsCollector.REMOTE_CHECK_STRATEGY import git4idea.branch.GitBranchUtil import git4idea.commands.Git import git4idea.commands.GitCommand import git4idea.commands.GitLineHandler import git4idea.config.GitConfigUtil import git4idea.config.GitExecutableManager +import git4idea.config.GitIncomingRemoteCheckStrategy import git4idea.config.GitSaveChangesPolicy import git4idea.config.GitVcsApplicationSettings import git4idea.config.GitVcsSettings @@ -57,7 +59,7 @@ import kotlin.io.path.isDirectory import kotlin.io.path.isRegularFile internal class GitStatisticsCollector : ProjectUsagesCollector() { - private val GROUP = EventLogGroup("git.configuration", 23) + private val GROUP = EventLogGroup("git.configuration", 24) override fun getGroup(): EventLogGroup = GROUP @@ -76,6 +78,7 @@ internal class GitStatisticsCollector : ProjectUsagesCollector() { addIfDiffers(set, settings, defaultSettings, { it.syncSetting }, REPO_SYNC, REPO_SYNC_VALUE) addIfDiffers(set, settings, defaultSettings, { it.updateMethod }, UPDATE_TYPE, UPDATE_TYPE_VALUE) addIfDiffers(set, settings, defaultSettings, { it.saveChangesPolicy }, SAVE_POLICY, SAVE_POLICY_VALUE) + addIfDiffers(set, settings, defaultSettings, { it.incomingCommitsCheckStrategy }, INCOMING_COMMITS_CHECK_STRATEGY, GitOperationsCollector.REMOTE_CHECK_STRATEGY) addBoolIfDiffers(set, settings, defaultSettings, { it.autoUpdateIfPushRejected() }, PUSH_AUTO_UPDATE) addBoolIfDiffers(set, settings, defaultSettings, { it.warnAboutCrlf() }, WARN_CRLF) @@ -231,6 +234,11 @@ internal class GitStatisticsCollector : ProjectUsagesCollector() { private val SAVE_POLICY_VALUE = EventFields.Enum("value", GitSaveChangesPolicy::class.java) { it.name.lowercase() } private val SAVE_POLICY = GROUP.registerVarargEvent("save.policy", SAVE_POLICY_VALUE) + private val INCOMING_COMMITS_CHECK_STRATEGY = + GROUP.registerVarargEvent("incoming_commits_check_strategy", + "Non-default value for incoming commits check strategy", + REMOTE_CHECK_STRATEGY) + private val PUSH_AUTO_UPDATE = GROUP.registerVarargEvent("push.autoupdate", EventFields.Enabled) private val WARN_CRLF = GROUP.registerVarargEvent("warn.about.crlf", EventFields.Enabled) diff --git a/plugins/git4idea/src/git4idea/branch/GitBranchIncomingOutgoingManager.java b/plugins/git4idea/src/git4idea/branch/GitBranchIncomingOutgoingManager.java index 7cfa5639e7cf..dc2c1eb00b86 100644 --- a/plugins/git4idea/src/git4idea/branch/GitBranchIncomingOutgoingManager.java +++ b/plugins/git4idea/src/git4idea/branch/GitBranchIncomingOutgoingManager.java @@ -31,6 +31,7 @@ import com.intellij.vcs.git.branch.GitInOutProjectState; import com.intellij.vcs.log.Hash; import com.intellij.vcsUtil.VcsFileUtil; import git4idea.GitLocalBranch; +import git4idea.GitOperationsCollector; import git4idea.GitRemoteBranch; import git4idea.commands.Git; import git4idea.commands.GitAuthenticationListener; @@ -72,6 +73,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; import com.intellij.externalProcessAuthHelper.AuthenticationMode; @@ -293,25 +295,33 @@ public final class GitBranchIncomingOutgoingManager implements GitRepositoryChan private void requestRemoteInfo(GitIncomingRemoteCheckStrategy remoteCheckStrategy, List repositories) { myLocalBranchesToFetch.remove(repositories); - switch (remoteCheckStrategy) { - case FETCH -> { - LOG.info("Fetching %d repositories".formatted(repositories.size())); - List remotesToFetch = new ArrayList<>(); - for (GitRepository repository : repositories) { - for (GitRemote remote : repository.getRemotes()) { - remotesToFetch.add(new GitFetchSpec(repository, remote, getAuthenticationMode(repository, remote))); + if (remoteCheckStrategy == GitIncomingRemoteCheckStrategy.NONE) { + LOG.debug("Remote check disabled"); + return; + } + + AtomicBoolean success = new AtomicBoolean(false); + try { + switch (remoteCheckStrategy) { + case FETCH -> { + LOG.info("Fetching %d repositories".formatted(repositories.size())); + List remotesToFetch = new ArrayList<>(); + for (GitRepository repository : repositories) { + for (GitRemote remote : repository.getRemotes()) { + remotesToFetch.add(new GitFetchSpec(repository, remote, getAuthenticationMode(repository, remote))); + } } + success.set(GitFetchSupport.fetchSupport(myProject).fetch(remotesToFetch).isSuccessful()); + } + case LS_REMOTE -> { + LOG.info("Listing remote info for %d repositories".formatted(repositories.size())); + repositories.forEach(r -> myLocalBranchesToFetch.put(r, calculateBranchesToFetch(r, () -> success.set(false)))); } - GitFetchSupport.fetchSupport(myProject).fetch(remotesToFetch); - } - case LS_REMOTE -> { - LOG.info("Listing remote info for %d repositories".formatted(repositories.size())); - repositories.forEach(r -> myLocalBranchesToFetch.put(r, calculateBranchesToFetch(r))); - } - case NONE -> { - LOG.debug("Remote check disabled"); } } + finally { + GitOperationsCollector.logRemoteInfoRequest(myProject, remoteCheckStrategy, success.get()); + } } @ApiStatus.Internal @@ -354,20 +364,22 @@ public final class GitBranchIncomingOutgoingManager implements GitRepositoryChan scheduleUpdate(); } - private @NotNull Map calculateBranchesToFetch(@NotNull GitRepository repository) { + private @NotNull Map calculateBranchesToFetch(@NotNull GitRepository repository, + @NotNull Runnable onError) { Map result = new HashMap<>(); groupTrackInfoByRemotes(repository).entrySet() - .forEach(entry -> result.putAll(calcBranchesToFetchForRemote(repository, entry.getKey(), entry.getValue()))); + .forEach(entry -> result.putAll(calcBranchesToFetchForRemote(repository, entry.getKey(), entry.getValue(), onError))); return result; } private @NotNull Map calcBranchesToFetchForRemote(@NotNull GitRepository repository, @NotNull GitRemote gitRemote, - @NotNull Collection trackInfoList) { + @NotNull Collection trackInfoList, + @NotNull Runnable onError) { Map result = new HashMap<>(); GitBranchesCollection branchesCollection = repository.getBranches(); final Map remoteNameWithHash = - lsRemote(repository, gitRemote, ContainerUtil.map(trackInfoList, info -> info.getRemoteBranch().getNameForRemoteOperations())); + lsRemote(repository, gitRemote, ContainerUtil.map(trackInfoList, info -> info.getRemoteBranch().getNameForRemoteOperations()), onError); for (Map.Entry hashEntry : remoteNameWithHash.entrySet()) { String remoteBranchName = hashEntry.getKey(); @@ -435,7 +447,8 @@ public final class GitBranchIncomingOutgoingManager implements GitRepositoryChan private @NotNull Map lsRemote(@NotNull GitRepository repository, @NotNull GitRemote remote, - @NotNull List branchRefNames) { + @NotNull List branchRefNames, + @NotNull Runnable onError) { Map result = new HashMap<>(); if (!supportsIncomingOutgoing()) return result; @@ -452,6 +465,9 @@ public final class GitBranchIncomingOutgoingManager implements GitRepositoryChan result.putAll(getResolvedHashes(hashWithNameMap)); myAuthSuccessMap.putValue(repository, remote); } + else { + onError.run(); + } }); return result; } diff --git a/plugins/git4idea/src/git4idea/fetch/GitFetchResult.kt b/plugins/git4idea/src/git4idea/fetch/GitFetchResult.kt index 0b002a949574..5ee50e7dc5b5 100644 --- a/plugins/git4idea/src/git4idea/fetch/GitFetchResult.kt +++ b/plugins/git4idea/src/git4idea/fetch/GitFetchResult.kt @@ -17,4 +17,6 @@ interface GitFetchResult { fun showNotificationIfFailed(title: @NlsContexts.NotificationTitle String): Boolean fun throwExceptionIfFailed() + + fun isSuccessful(): Boolean } \ No newline at end of file diff --git a/plugins/git4idea/src/git4idea/fetch/GitFetchSupportImpl.kt b/plugins/git4idea/src/git4idea/fetch/GitFetchSupportImpl.kt index 93031e1c6725..8d83635dbc2f 100644 --- a/plugins/git4idea/src/git4idea/fetch/GitFetchSupportImpl.kt +++ b/plugins/git4idea/src/git4idea/fetch/GitFetchSupportImpl.kt @@ -323,6 +323,8 @@ internal class GitFetchSupportImpl(private val project: Project) : GitFetchSuppo private val isFailed = results.values.any { !it.totallySuccessful() } + override fun isSuccessful(): Boolean = !isFailed + override fun showNotification() { doShowNotification() }