vcs-ignore: optimization: do not explicitly mark ignored files dirty in git (IDEA-CR-46072)

* Untracked files holder should mark root dirty after ignored rescan completes.
* VcsRepositoryIgnoredFilesHolder API extended in a way to support "actionAfterRescan".
This commit is contained in:
Dmitry Zhuravlev
2019-04-15 16:04:15 +03:00
parent 37da2387a7
commit 82850cbb03
4 changed files with 16 additions and 10 deletions
@@ -5,6 +5,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
@@ -16,6 +17,8 @@ public interface VcsRepositoryIgnoredFilesHolder extends Disposable {
void startRescan();
void startRescan(@Nullable Runnable actionAfterRescan);
boolean isInUpdateMode();
int getSize();
@@ -106,9 +106,13 @@ abstract class VcsRepositoryIgnoredFilesHolderBase<REPOSITORY : Repository>(
protected abstract fun scanTurnedOff(): Boolean
override fun startRescan() {
startRescan(null)
}
override fun startRescan(actionAfterRescan: Runnable?) {
if (scanTurnedOff()) return
queueIgnoreUpdate(isFullRescan = true) {
queueIgnoreUpdate(isFullRescan = true, doAfterRescan = actionAfterRescan) {
doRescan()
}
}
@@ -137,7 +141,7 @@ abstract class VcsRepositoryIgnoredFilesHolderBase<REPOSITORY : Repository>(
}
}
private fun queueIgnoreUpdate(isFullRescan: Boolean, action: () -> Set<FilePath>) {
private fun queueIgnoreUpdate(isFullRescan: Boolean, doAfterRescan: Runnable? = null, action: () -> Set<FilePath>) {
//full rescan should have the same update identity, so multiple full rescans can be swallowed instead of spawning new threads
val updateIdentity = if (isFullRescan) "${rescanIdentityName}_full" else ObjectUtils.sentinel(rescanIdentityName)
updateQueue.queue(object : Update(updateIdentity) {
@@ -150,6 +154,7 @@ abstract class VcsRepositoryIgnoredFilesHolderBase<REPOSITORY : Repository>(
val ignored = action()
inUpdateMode.set(false)
fireUpdateFinished(ignored)
doAfterRescan?.run()
}
})
})
@@ -12,9 +12,7 @@ import com.intellij.openapi.vcs.changes.ChangesViewI;
import com.intellij.openapi.vcs.changes.ChangesViewManager;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.util.StopWatch;
import com.intellij.vcsUtil.VcsFileUtil;
import git4idea.GitLocalBranch;
import git4idea.GitUtil;
import git4idea.GitVcs;
@@ -283,7 +281,6 @@ public class GitRepositoryImpl extends RepositoryImpl implements GitRepository {
public void updateFinished(@NotNull Collection<FilePath> ignoredPaths) {
if(myProject.isDisposed()) return;
VcsFileUtil.markFilesDirty(myProject, ContainerUtil.newArrayList(ignoredPaths));
myChangesViewI.scheduleRefresh();
}
}
@@ -252,9 +252,10 @@ public class GitUntrackedFilesHolder implements Disposable, AsyncVfsEventsListen
// if index has changed, no need to refresh specific files - we get the full status of all files
if (allChanged) {
LOG.debug(String.format("GitUntrackedFilesHolder: total refresh is needed, marking %s recursively dirty", myRoot));
myDirtyScopeManager.dirDirtyRecursively(myRoot);
rescanIgnoredFiles();
rescanIgnoredFiles(() -> {
LOG.debug(String.format("GitUntrackedFilesHolder: total refresh is needed, marking %s recursively dirty", myRoot));
myDirtyScopeManager.dirDirtyRecursively(myRoot);
});
synchronized (LOCK) {
myReady = false;
}
@@ -296,8 +297,8 @@ public class GitUntrackedFilesHolder implements Disposable, AsyncVfsEventsListen
return path.endsWith(GitRepositoryFiles.GITIGNORE) || myRepositoryFiles.isExclude(path);
}
private void rescanIgnoredFiles() { //TODO move to ignore manager
myRepository.getIgnoredFilesHolder().startRescan();
private void rescanIgnoredFiles(@NotNull Runnable doAfterRescan) { //TODO move to ignore manager
myRepository.getIgnoredFilesHolder().startRescan(doAfterRescan);
}
private boolean notIgnored(@Nullable VirtualFile file) {