From d562dab64abc385a59041ada6680783cbed6484c Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Tue, 10 Apr 2018 18:35:53 +0300 Subject: [PATCH] vcs: replace calls to FileStatusManager with ChangeListManager.getStatus FileStatusManager is used to paint files with different colors. ChangeListManager is used to determine actual file status (ex: whether file has non-empty history in vcs). ex: ChangelistConflictFileStatusProvider can mess up with FileStatusManager and ADDED files will be reported as ADDED_OUTSIDE, breaking status checks. --- .../openapi/vcs/FileStatusManager.java | 17 ++++++++- .../intellij/openapi/vcs/VcsVFSListener.java | 2 +- .../vcs/actions/AnnotateDiffViewerAction.java | 2 +- .../vcs/actions/AnnotateLocalFileAction.java | 3 +- .../vcs/actions/CommonCheckinFilesAction.java | 2 +- .../vcs/actions/DiffActionExecutor.java | 6 +-- .../vcs/annotate/AnnotationsPreloader.java | 8 +++- .../changes/SelectInChangesViewTarget.java | 3 +- .../actions/ScheduleForAdditionAction.java | 9 +++-- .../src/git4idea/diff/GitDiffProvider.java | 38 +++++++++---------- .../zmlx/hg4idea/action/HgMarkResolved.java | 7 ++-- 11 files changed, 56 insertions(+), 41 deletions(-) diff --git a/platform/editor-ui-api/src/com/intellij/openapi/vcs/FileStatusManager.java b/platform/editor-ui-api/src/com/intellij/openapi/vcs/FileStatusManager.java index 21af75a25f92..5510069fdf3c 100644 --- a/platform/editor-ui-api/src/com/intellij/openapi/vcs/FileStatusManager.java +++ b/platform/editor-ui-api/src/com/intellij/openapi/vcs/FileStatusManager.java @@ -6,7 +6,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; -import java.awt.Color; +import java.awt.*; /** * @author mike @@ -16,6 +16,16 @@ public abstract class FileStatusManager { return project.getComponent(FileStatusManager.class); } + /** + * Returns color that is associated with passed file in vcs subsystem. + *

+ * Users are discouraged from comparing returned value with a constant, because it might be vcs-specific (HgChangeProvider#RENAMED) + * or affected by other means (ChangelistConflictFileStatusProvider#MODIFIED_OUTSIDE). + * + * @See com.intellij.openapi.vcs.changes.ChangeListManager#getStatus + * @See com.intellij.openapi.vcs.FileStatusFactory + * @See com.intellij.openapi.vcs.impl.FileStatusProvider + */ public abstract FileStatus getStatus(@NotNull VirtualFile file); public abstract void fileStatusesChanged(); @@ -30,6 +40,11 @@ public abstract class FileStatusManager { public abstract Color getNotChangedDirectoryColor(@NotNull VirtualFile file); + /** + * @See VcsConfiguration#SHOW_DIRTY_RECURSIVELY + * @See com.intellij.openapi.vcs.FileStatus#NOT_CHANGED_IMMEDIATE + * @See com.intellij.openapi.vcs.FileStatus#NOT_CHANGED_RECURSIVE + */ @NotNull public FileStatus getRecursiveStatus(@NotNull VirtualFile file) { FileStatus status = getStatus(file); diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java index 410d7e712457..8f768235e038 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java @@ -271,7 +271,7 @@ public abstract class VcsVFSListener implements Disposable { } protected void processMovedFile(VirtualFile file, String newParentPath, String newName) { - final FileStatus status = FileStatusManager.getInstance(myProject).getStatus(file); + final FileStatus status = ChangeListManager.getInstance(myProject).getStatus(file); LOG.debug("Checking moved file ", file, "; status=", status); if (status == FileStatus.IGNORED) { if (file.getParent() != null) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateDiffViewerAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateDiffViewerAction.java index 0f5055c019f2..3ad5f9c9b474 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateDiffViewerAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateDiffViewerAction.java @@ -267,7 +267,7 @@ public class AnnotateDiffViewerAction { final AnnotationProvider annotationProvider = vcs.getAnnotationProvider(); if (annotationProvider == null) return null; - FileStatus fileStatus = FileStatusManager.getInstance(project).getStatus(file); + FileStatus fileStatus = ChangeListManager.getInstance(project).getStatus(file); if (fileStatus == FileStatus.UNKNOWN || fileStatus == FileStatus.ADDED || fileStatus == FileStatus.IGNORED) { return null; } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateLocalFileAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateLocalFileAction.java index 27d70ae4e776..fcbc849762e3 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateLocalFileAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/AnnotateLocalFileAction.java @@ -33,6 +33,7 @@ import com.intellij.openapi.util.Ref; import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.annotate.AnnotationProvider; import com.intellij.openapi.vcs.annotate.FileAnnotation; +import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -58,7 +59,7 @@ public class AnnotateLocalFileAction { final AnnotationProvider annotationProvider = vcs.getAnnotationProvider(); if (annotationProvider == null) return false; - final FileStatus fileStatus = FileStatusManager.getInstance(project).getStatus(file); + FileStatus fileStatus = ChangeListManager.getInstance(project).getStatus(file); if (fileStatus == FileStatus.UNKNOWN || fileStatus == FileStatus.ADDED || fileStatus == FileStatus.IGNORED) { return false; } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/CommonCheckinFilesAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/CommonCheckinFilesAction.java index c38b60b12e7f..5b02211548c1 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/CommonCheckinFilesAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/CommonCheckinFilesAction.java @@ -88,7 +88,7 @@ public class CommonCheckinFilesAction extends AbstractCommonCheckinAction { @Override protected boolean approximatelyHasRoots(@NotNull VcsContext dataContext) { - FileStatusManager manager = FileStatusManager.getInstance(dataContext.getProject()); + ChangeListManager manager = ChangeListManager.getInstance(dataContext.getProject()); return getRootsStream(dataContext) .map(FilePath::getVirtualFile) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/DiffActionExecutor.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/DiffActionExecutor.java index b61e0630b638..e02073c76e92 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/DiffActionExecutor.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/actions/DiffActionExecutor.java @@ -40,6 +40,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.changes.ByteBackedContentRevision; +import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vcs.changes.ContentRevision; import com.intellij.openapi.vcs.diff.DiffProvider; import com.intellij.openapi.vcs.diff.ItemLatestState; @@ -138,9 +139,8 @@ public abstract class DiffActionExecutor { boolean inverted = false; String title1; String title2; - final FileStatus status = FileStatusManager.getInstance(myProject).getStatus(mySelectedFile); - if (status == null || FileStatus.NOT_CHANGED.equals(status) || FileStatus.UNKNOWN.equals(status) || - FileStatus.IGNORED.equals(status)) { + final FileStatus status = ChangeListManager.getInstance(myProject).getStatus(mySelectedFile); + if (FileStatus.NOT_CHANGED.equals(status) || FileStatus.UNKNOWN.equals(status) || FileStatus.IGNORED.equals(status)) { final VcsRevisionNumber currentRevision = myDiffProvider.getCurrentRevision(mySelectedFile); inverted = revisionNumber.compareTo(currentRevision) > 0; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/annotate/AnnotationsPreloader.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/annotate/AnnotationsPreloader.java index 7ca20b862429..d2f25e4a5cec 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/annotate/AnnotationsPreloader.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/annotate/AnnotationsPreloader.java @@ -22,7 +22,11 @@ import com.intellij.openapi.fileEditor.FileEditorManagerEvent; import com.intellij.openapi.fileEditor.FileEditorManagerListener; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.registry.Registry; -import com.intellij.openapi.vcs.*; +import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.openapi.vcs.ProjectLevelVcsManager; +import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ui.update.MergingUpdateQueue; import com.intellij.util.ui.update.Update; @@ -71,7 +75,7 @@ public class AnnotationsPreloader { } if (!FileEditorManager.getInstance(myProject).isFileOpen(file)) return; - FileStatus fileStatus = FileStatusManager.getInstance(myProject).getStatus(file); + FileStatus fileStatus = ChangeListManager.getInstance(myProject).getStatus(file); if (fileStatus == FileStatus.UNKNOWN || fileStatus == FileStatus.ADDED || fileStatus == FileStatus.IGNORED) { return; } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/SelectInChangesViewTarget.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/SelectInChangesViewTarget.java index 66d7b1cc5780..da6b7e41e3ce 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/SelectInChangesViewTarget.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/SelectInChangesViewTarget.java @@ -20,7 +20,6 @@ import com.intellij.ide.SelectInTarget; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.FileStatus; -import com.intellij.openapi.vcs.FileStatusManager; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsBundle; import com.intellij.openapi.vcs.changes.ui.ChangesViewContentManager; @@ -44,7 +43,7 @@ public class SelectInChangesViewTarget implements SelectInTarget, DumbAware { @Override public boolean canSelect(final SelectInContext context) { final VirtualFile file = context.getVirtualFile(); - FileStatus fileStatus = FileStatusManager.getInstance(myProject).getStatus(file); + FileStatus fileStatus = ChangeListManager.getInstance(myProject).getStatus(file); return ProjectLevelVcsManager.getInstance(myProject).getAllActiveVcss().length != 0 && !fileStatus.equals(FileStatus.NOT_CHANGED); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ScheduleForAdditionAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ScheduleForAdditionAction.java index 3cc61225d252..7517c0c0afc7 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ScheduleForAdditionAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ScheduleForAdditionAction.java @@ -26,6 +26,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.changes.Change; +import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vcs.changes.ChangeListManagerImpl; import com.intellij.openapi.vcs.changes.LocalChangeList; import com.intellij.openapi.vcs.changes.ui.ChangesBrowserBase; @@ -99,22 +100,22 @@ public class ScheduleForAdditionAction extends AnAction implements DumbAware { @NotNull private Stream getUnversionedFiles(@NotNull AnActionEvent e, @NotNull Project project) { ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project); - FileStatusManager fileStatusManager = FileStatusManager.getInstance(project); + ChangeListManager changeListManager = ChangeListManager.getInstance(project); boolean hasExplicitUnversioned = !isEmpty(e.getData(ChangesListView.UNVERSIONED_FILES_DATA_KEY)); return hasExplicitUnversioned ? e.getRequiredData(ChangesListView.UNVERSIONED_FILES_DATA_KEY) : checkVirtualFiles(e) - ? notNullize(e.getData(VcsDataKeys.VIRTUAL_FILE_STREAM)).filter(file -> isFileUnversioned(file, vcsManager, fileStatusManager)) + ? notNullize(e.getData(VcsDataKeys.VIRTUAL_FILE_STREAM)).filter(file -> isFileUnversioned(file, vcsManager, changeListManager)) : Stream.empty(); } private boolean isFileUnversioned(@NotNull VirtualFile file, @NotNull ProjectLevelVcsManager vcsManager, - @NotNull FileStatusManager fileStatusManager) { + @NotNull ChangeListManager changeListManager) { AbstractVcs vcs = vcsManager.getVcsFor(file); return vcs != null && !vcs.areDirectoriesVersionedItems() && file.isDirectory() || - isStatusForAddition(fileStatusManager.getStatus(file)); + isStatusForAddition(changeListManager.getStatus(file)); } protected boolean isStatusForAddition(FileStatus status) { diff --git a/plugins/git4idea/src/git4idea/diff/GitDiffProvider.java b/plugins/git4idea/src/git4idea/diff/GitDiffProvider.java index d09d951b2a1b..9a7fc3e70ca0 100644 --- a/plugins/git4idea/src/git4idea/diff/GitDiffProvider.java +++ b/plugins/git4idea/src/git4idea/diff/GitDiffProvider.java @@ -17,7 +17,11 @@ package git4idea.diff; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.vcs.*; +import com.intellij.openapi.vcs.CommittedChangesProvider; +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vcs.changes.ContentRevision; import com.intellij.openapi.vcs.diff.DiffMixin; import com.intellij.openapi.vcs.diff.DiffProvider; @@ -35,13 +39,10 @@ import git4idea.GitVcs; import git4idea.history.GitFileHistory; import git4idea.history.GitHistoryUtils; import git4idea.i18n.GitBundle; -import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; import java.util.Collections; -import java.util.Set; /** * Git diff provider @@ -51,20 +52,7 @@ public class GitDiffProvider implements DiffProvider, DiffMixin { * The context project */ private final Project myProject; - /** - * The status manager for the project - */ - private final FileStatusManager myStatusManager; - /** - * - */ - private static final Set ourGoodStatuses; - - static { - ourGoodStatuses = new THashSet<>(); - ourGoodStatuses.addAll( - Arrays.asList(FileStatus.NOT_CHANGED, FileStatus.DELETED, FileStatus.MODIFIED, FileStatus.MERGE, FileStatus.MERGED_WITH_CONFLICTS)); - } + private final ChangeListManager myChangeListManager; /** * A constructor @@ -73,7 +61,7 @@ public class GitDiffProvider implements DiffProvider, DiffMixin { */ public GitDiffProvider(@NotNull Project project) { myProject = project; - myStatusManager = FileStatusManager.getInstance(myProject); + myChangeListManager = ChangeListManager.getInstance(myProject); } /** @@ -114,7 +102,7 @@ public class GitDiffProvider implements DiffProvider, DiffMixin { if (file.isDirectory()) { return null; } - if (!ourGoodStatuses.contains(myStatusManager.getStatus(file))) { + if (!hasGoodFileStatus(file)) { return null; } try { @@ -125,6 +113,14 @@ public class GitDiffProvider implements DiffProvider, DiffMixin { } } + private boolean hasGoodFileStatus(VirtualFile file) { + FileStatus status = myChangeListManager.getStatus(file); + return status == FileStatus.NOT_CHANGED || + status == FileStatus.DELETED || + status == FileStatus.MODIFIED || + status == FileStatus.MERGED_WITH_CONFLICTS; + } + /** * {@inheritDoc} */ @@ -182,7 +178,7 @@ public class GitDiffProvider implements DiffProvider, DiffMixin { } final VirtualFile vf = filePath.getVirtualFile(); if (vf != null) { - if (! ourGoodStatuses.contains(myStatusManager.getStatus(vf))) { + if (!hasGoodFileStatus(vf)) { return null; } } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMarkResolved.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMarkResolved.java index 828b95a0b4f2..6c14d18e25cd 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMarkResolved.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMarkResolved.java @@ -15,8 +15,7 @@ package org.zmlx.hg4idea.action; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.FileStatus; -import com.intellij.openapi.vcs.FileStatusManager; -import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.vcsUtil.VcsUtil; import org.zmlx.hg4idea.HgVcs; @@ -27,8 +26,8 @@ import java.util.List; public class HgMarkResolved extends HgAbstractFilesAction { protected boolean isEnabled(Project project, HgVcs vcs, VirtualFile file) { - final FileStatus fileStatus = FileStatusManager.getInstance(project).getStatus(file); - return fileStatus != null && FileStatus.MERGED_WITH_CONFLICTS.equals(fileStatus); + final FileStatus fileStatus = ChangeListManager.getInstance(project).getStatus(file); + return FileStatus.MERGED_WITH_CONFLICTS.equals(fileStatus); } protected void batchPerform(Project project, HgVcs activeVcs,