diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java index d35870624b68..a2ad6500fefa 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgVFSListener.java @@ -29,20 +29,22 @@ import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.AppUIUtil; import com.intellij.util.Function; +import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.VcsBackgroundTask; import com.intellij.vcsUtil.VcsUtil; import org.jetbrains.annotations.NotNull; import org.zmlx.hg4idea.command.*; +import org.zmlx.hg4idea.provider.HgLocalIgnoredHolder; import org.zmlx.hg4idea.util.HgUtil; import java.util.*; import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; /** * Listens to VFS events (such as adding or deleting bunch of files) and performs necessary operations with the VCS. - * @author Kirill Likhodedov */ public class HgVFSListener extends VcsVFSListener { @@ -100,9 +102,11 @@ public class HgVFSListener extends VcsVFSListener { final Collection files = e.getValue(); pi.setText(repo.getPresentableUrl()); try { - untrackedFiles - .addAll(new HgStatusCommand.Builder(false).unknown(true).removed(true).build(myProject) - .getFiles(repo, new ArrayList<>(files))); + Collection untrackedForRepo = new HgStatusCommand.Builder(false).unknown(true).removed(true).build(myProject) + .getFiles(repo, new ArrayList<>(files)); + untrackedFiles.addAll(untrackedForRepo); + List ignoredForRepo = files.stream().filter(file -> !untrackedForRepo.contains(file)).collect(Collectors.toList()); + getIgnoreRepoHolder(repo).addFiles(ignoredForRepo); } catch (final VcsException ex) { UIUtil.invokeLaterIfNeeded(new Runnable() { @@ -127,6 +131,10 @@ public class HgVFSListener extends VcsVFSListener { }.queue(); } + @NotNull + HgLocalIgnoredHolder getIgnoreRepoHolder(@NotNull VirtualFile repoRoot) { + return ObjectUtils.assertNotNull(HgUtil.getRepositoryManager(myProject).getRepositoryForRootQuick(repoRoot)).getLocalIgnoredHolder(); + } /** * The version of execute add before overriding * @@ -230,6 +238,9 @@ public class HgVFSListener extends VcsVFSListener { skipNotUnderHg(filesToDelete); skipNotUnderHg(filesToConfirmDeletion); + filesToDelete.removeAll(processAndGetVcsIgnored(filesToDelete)); + filesToConfirmDeletion.removeAll(processAndGetVcsIgnored(filesToConfirmDeletion)); + // newly added files (which were added to the repo but never committed) should be removed from the VCS, // but without user confirmation. for (Iterator it = filesToConfirmDeletion.iterator(); it.hasNext(); ) { @@ -267,6 +278,14 @@ public class HgVFSListener extends VcsVFSListener { }.queue(); } + @NotNull + private List processAndGetVcsIgnored(@NotNull List filePaths) { + Map> groupFilePathsByHgRoots = HgUtil.groupFilePathsByHgRoots(myProject, filePaths); + return groupFilePathsByHgRoots.entrySet().stream() + .map(entry -> getIgnoreRepoHolder(entry.getKey()).removeIgnoredFiles(entry.getValue())) + .flatMap(List::stream).collect(Collectors.toList()); + } + /** * Changes the given collection of files by filtering out unversioned files and * files which are not under Mercurial repository. diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgLocalIgnoredHolder.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgLocalIgnoredHolder.java index 964d8924a3e8..acc5560dd19f 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgLocalIgnoredHolder.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgLocalIgnoredHolder.java @@ -17,16 +17,21 @@ package org.zmlx.hg4idea.provider; import com.intellij.openapi.Disposable; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Alarm; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.update.MergingUpdateQueue; import com.intellij.util.ui.update.Update; +import com.intellij.vcsUtil.VcsUtil; import org.jetbrains.annotations.NotNull; import org.zmlx.hg4idea.command.HgStatusCommand; import org.zmlx.hg4idea.repo.HgRepository; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -84,6 +89,36 @@ public class HgLocalIgnoredHolder implements Disposable { } } + @NotNull + public List removeIgnoredFiles(@NotNull Collection files) { + List removedIgnoredFiles = ContainerUtil.newArrayList(); + try { + SET_LOCK.writeLock().lock(); + Iterator iter = myIgnoredSet.iterator(); + while (iter.hasNext()) { + FilePath filePath = VcsUtil.getFilePath(iter.next()); + if (files.contains(filePath)) { + iter.remove(); + removedIgnoredFiles.add(filePath); + } + } + } + finally { + SET_LOCK.writeLock().unlock(); + } + return removedIgnoredFiles; + } + + public void addFiles(@NotNull List files) { + try { + SET_LOCK.writeLock().lock(); + myIgnoredSet.addAll(files); + } + finally { + SET_LOCK.writeLock().unlock(); + } + } + public boolean contains(@NotNull VirtualFile file) { try { SET_LOCK.readLock().lock();