mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[git-stash] show a warning when index contains files other than selected
When the "git stash push" command is called for the list of files, the whole index state is saved to the stash regardless of which files were specified to the command. Because of this, stash created in this situation would contain unexpected changes. The warning is meant to notify the user about such behavior. GitOrigin-RevId: 92ae7335703096a62aa06d89f09ccb63e84e8af7
This commit is contained in:
committed by
intellij-monorepo-bot
parent
5090b8b301
commit
92290b3c81
@@ -220,7 +220,7 @@ public class VcsNotifier {
|
||||
public Notification notifyMinorWarning(@NonNls @Nullable String displayId,
|
||||
@NotificationTitle @NotNull String title,
|
||||
@NotificationContent @NotNull String message) {
|
||||
return notifyMinorWarning(displayId, title, message, null);
|
||||
return notifyMinorWarning(displayId, title, message, (NotificationListener)null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -229,6 +229,14 @@ public class VcsNotifier {
|
||||
return notify(STANDARD_NOTIFICATION, displayId, "", message, NotificationType.WARNING, (NotificationListener)null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Notification notifyMinorWarning(@NonNls @Nullable String displayId,
|
||||
@NotificationTitle @NotNull String title,
|
||||
@NotificationContent @NotNull String message,
|
||||
NotificationAction... actions) {
|
||||
return notify(STANDARD_NOTIFICATION, displayId, title, message, NotificationType.WARNING, actions);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Notification notifyMinorWarning(@NonNls @Nullable String displayId,
|
||||
@NotificationTitle @NotNull String title,
|
||||
|
||||
@@ -421,6 +421,9 @@ stash.files.in.roots.success=Files in {0} stashed successfully
|
||||
stash.view.stashes.link=View Git stashes
|
||||
stash.enable.stashes.link=Enable and view "{0}" tab
|
||||
|
||||
stash.changes.non.empty.index.for.roots.notification.text=Staging area in {0} contains modifications to other files which were saved to the stash
|
||||
stash.changes.non.empty.index.notification.action=Do not show again
|
||||
|
||||
tag.action.name=Tag
|
||||
tag.button=Create Tag
|
||||
tag.commit.label=&Commit:
|
||||
|
||||
@@ -87,6 +87,7 @@ class GitNotificationIdsHolder : NotificationIdsHolder {
|
||||
STASH_SUCCESSFUL,
|
||||
STASH_FAILED,
|
||||
STASH_LOCAL_CHANGES_DETECTED,
|
||||
STASH_NON_EMPTY_INDEX_DETECTED,
|
||||
TAG_CREATED,
|
||||
TAG_NOT_CREATED,
|
||||
TAG_DELETED,
|
||||
@@ -196,6 +197,7 @@ class GitNotificationIdsHolder : NotificationIdsHolder {
|
||||
const val STASH_SUCCESSFUL = "git.stash.successful"
|
||||
const val STASH_FAILED = "git.stash.failed"
|
||||
const val STASH_LOCAL_CHANGES_DETECTED = "git.stash.local.changes.detected"
|
||||
const val STASH_NON_EMPTY_INDEX_DETECTED = "git.stash.non.empty.index.detected"
|
||||
const val TAG_CREATED = "git.tag.created"
|
||||
const val TAG_NOT_CREATED = "git.tag.not.created"
|
||||
const val TAG_DELETED = "git.tag.deleted"
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package git4idea.index.actions
|
||||
|
||||
import com.intellij.ide.util.PropertiesComponent
|
||||
import com.intellij.notification.NotificationAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vcs.FilePath
|
||||
import com.intellij.openapi.vcs.VcsException
|
||||
import com.intellij.openapi.vcs.VcsNotifier
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import git4idea.GitNotificationIdsHolder
|
||||
import git4idea.GitStashUsageCollector
|
||||
import git4idea.commands.Git
|
||||
import git4idea.config.GitExecutableManager
|
||||
import git4idea.config.GitVersionSpecialty
|
||||
import git4idea.i18n.GitBundle
|
||||
import git4idea.index.GitStageTracker
|
||||
import git4idea.index.ui.GitFileStatusNode
|
||||
import git4idea.index.ui.NodeKind
|
||||
import git4idea.stash.GitStashOperations
|
||||
@@ -43,12 +49,46 @@ object GitStashOperation : StagingAreaOperation {
|
||||
refreshStash(project, root)
|
||||
}
|
||||
|
||||
override fun reportResult(project: Project, successfulRoots: Collection<VirtualFile>, exceptionsByRoot: MultiMap<VirtualFile, VcsException>) {
|
||||
super.reportResult(project, successfulRoots, exceptionsByRoot)
|
||||
override fun reportResult(project: Project,
|
||||
nodes: List<GitFileStatusNode>,
|
||||
successfulRoots: Collection<VirtualFile>,
|
||||
exceptionsByRoot: MultiMap<VirtualFile, VcsException>) {
|
||||
super.reportResult(project, nodes, successfulRoots, exceptionsByRoot)
|
||||
if (successfulRoots.isNotEmpty()) {
|
||||
GitStashOperations.showSuccessNotification(project, successfulRoots, !exceptionsByRoot.isEmpty)
|
||||
showNonEmptyStagingAreaNotification(project, nodes, successfulRoots)
|
||||
}
|
||||
}
|
||||
|
||||
private const val SHOW_NOTIFICATION_PROPERTY = "git.stash.notify.non.empty.index"
|
||||
|
||||
private fun showNonEmptyStagingAreaNotification(project: Project, nodes: List<GitFileStatusNode>, successfulRoots: Collection<VirtualFile>) {
|
||||
if (PropertiesComponent.getInstance(project).getBoolean(SHOW_NOTIFICATION_PROPERTY, true)) {
|
||||
val tracker = GitStageTracker.getInstance(project)
|
||||
val stagedRoots = tracker.state.stagedRoots
|
||||
|
||||
val stagedRootsToStash = mutableSetOf<VirtualFile>()
|
||||
for ((root, nodesInRoot) in nodes.filter { stagedRoots.contains(it.root) && successfulRoots.contains(it.root) }.groupBy { it.root }) {
|
||||
val paths = nodesInRoot.mapTo(mutableSetOf()) { it.filePath }
|
||||
if (tracker.stagedFiles(root).any { !paths.contains(it) }) {
|
||||
stagedRootsToStash.add(root)
|
||||
}
|
||||
}
|
||||
if (stagedRootsToStash.isEmpty()) return
|
||||
|
||||
val message = GitBundle.message("stash.changes.non.empty.index.for.roots.notification.text",
|
||||
GitStashOperations.getRootsText(project, stagedRootsToStash))
|
||||
val action = NotificationAction.createSimpleExpiring(GitBundle.message("stash.changes.non.empty.index.notification.action")) {
|
||||
PropertiesComponent.getInstance(project).setValue(SHOW_NOTIFICATION_PROPERTY, false)
|
||||
}
|
||||
VcsNotifier.getInstance(project).notifyMinorWarning(GitNotificationIdsHolder.STASH_NON_EMPTY_INDEX_DETECTED, "", message, action)
|
||||
}
|
||||
}
|
||||
|
||||
private fun GitStageTracker.stagedFiles(root: VirtualFile): Collection<FilePath> {
|
||||
val rootState = state.rootStates[root] ?: return emptyList()
|
||||
return rootState.statuses.filterValues { it.getStagedStatus() != null }.map { it.key }
|
||||
}
|
||||
}
|
||||
|
||||
class GitStageStashFilesAction : StagingAreaOperationAction(GitStashOperation) {
|
||||
|
||||
@@ -36,7 +36,7 @@ interface StagingAreaOperation {
|
||||
@Throws(VcsException::class)
|
||||
fun processPaths(project: Project, root: VirtualFile, nodes: List<GitFileStatusNode>)
|
||||
|
||||
fun reportResult(project: Project, successfulRoots: Collection<VirtualFile>, exceptionsByRoot: MultiMap<VirtualFile, VcsException>) {
|
||||
fun reportResult(project: Project, nodes: List<GitFileStatusNode>, successfulRoots: Collection<VirtualFile>, exceptionsByRoot: MultiMap<VirtualFile, VcsException>) {
|
||||
if (!exceptionsByRoot.isEmpty) {
|
||||
showErrorMessage(project, errorMessage, exceptionsByRoot.values())
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ fun performStageOperation(project: Project, nodes: List<GitFileStatusNode>, oper
|
||||
}
|
||||
}
|
||||
|
||||
operation.reportResult(project, successfulRoots, exceptions)
|
||||
operation.reportResult(project, nodes, successfulRoots, exceptions)
|
||||
stagingAreaActionInvoked()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,7 +311,7 @@ object GitStashOperations {
|
||||
return GitBundle.message("stash.files.in.roots.success", rootsText)
|
||||
}
|
||||
|
||||
private fun getRootsText(project: Project, roots: Collection<VirtualFile>): String {
|
||||
internal fun getRootsText(project: Project, roots: Collection<VirtualFile>): String {
|
||||
val rootsText = roots.joinToString(", ") { "'${VcsImplUtil.getShortVcsRootName(project, it)}'" }
|
||||
return StringUtil.shortenTextWithEllipsis(rootsText, 100, 0)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user