diff --git a/platform/platform-resources-en/src/messages/VcsBundle.properties b/platform/platform-resources-en/src/messages/VcsBundle.properties index eeef9e62167d..24f92ac5d9fa 100644 --- a/platform/platform-resources-en/src/messages/VcsBundle.properties +++ b/platform/platform-resources-en/src/messages/VcsBundle.properties @@ -543,6 +543,8 @@ dialog.enable.version.control.integration.select.vcs.label.text=Select a version dialog.enable.version.control.integration.hint.text=Version control settings can be configured in 'Settings | Version Control' confirmation.text.add.file=Do you want to schedule the following file for addition to VCS?\n{0} confirmation.title.add.file=Schedule for Addition +confirmation.title.add.file.to=Add file to {0}? +confirmation.title.add.files.to=Add files to {0}? confirmation.title.add.multiple.files=Select Files to Add to VCS waiting.changelists.update.for.show.commit.dialog.message=Commit dialog add.confirmation.label.text=When files are created with {0}: diff --git a/platform/vcs-impl/src/com/intellij/vcsUtil/VcsFileUtil.java b/platform/vcs-impl/src/com/intellij/vcsUtil/VcsFileUtil.java index 98a3d84eb6c2..98461e6818ca 100644 --- a/platform/vcs-impl/src/com/intellij/vcsUtil/VcsFileUtil.java +++ b/platform/vcs-impl/src/com/intellij/vcsUtil/VcsFileUtil.java @@ -15,15 +15,19 @@ */ package com.intellij.vcsUtil; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.ThrowableNotNullFunction; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vcs.FilePath; -import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; +import com.intellij.openapi.vcs.checkin.CheckinEnvironment; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ThrowableConsumer; @@ -33,6 +37,7 @@ import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -379,4 +384,70 @@ public class VcsFileUtil { return null; } + + public static void addFilesToVcsWithConfirmation(@NotNull Project project, VirtualFile... virtualFiles) { + addFilesToVcsWithConfirmation(project, Arrays.asList(virtualFiles)); + } + + /** + * Finds all VCSs related to the passed files, suggests user to add files to the respected VCSs honoring addition and silence settings + * and adds them if user or settings confirmed addition. Because of potentially long operation of collecting files it's highly recommended + * to invoke it on the pooled thread. Method works synchronously. + * + * @param project project we work in + * @param virtualFiles collection of virtual files to add; directories being added recursively + */ + public static void addFilesToVcsWithConfirmation(@NotNull Project project, + @NotNull Collection virtualFiles) { + if (virtualFiles.isEmpty()) { + return; + } + ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project); + Multimap vcsMap = ArrayListMultimap.create(); + for (VirtualFile createdFile : virtualFiles) { + AbstractVcs vcs = vcsManager.getVcsFor(createdFile); + if (vcs == null) { + continue; + } + VfsUtil.processFileRecursivelyWithoutIgnored(createdFile, (virtualFile) -> vcsMap.put(vcs, virtualFile)); + } + + for (AbstractVcs vcs : vcsMap.keySet()) { + VcsShowConfirmationOption addOption = + vcsManager.getStandardConfirmation(VcsConfiguration.StandardConfirmation.ADD, vcs); + if (addOption.getValue() == VcsShowConfirmationOption.Value.DO_NOTHING_SILENTLY) return; + List filesList = new ArrayList<>(vcsMap.get(vcs)); + if (addOption.getValue() == VcsShowConfirmationOption.Value.DO_ACTION_SILENTLY) { + performAdditions(vcs, filesList); + } + else { + AbstractVcsHelper helper = AbstractVcsHelper.getInstance(project); + + Ref> filesToAdd = Ref.create(); + + ApplicationManager.getApplication().invokeAndWait(() -> filesToAdd.set( + helper + .selectFilesToProcess( + new ArrayList<>(filesList), + VcsBundle.message("confirmation.title.add.files.to", vcs.getDisplayName()), + null, + VcsBundle.message("confirmation.title.add.file.to", vcs.getDisplayName()), + null, + addOption)) + ); + + if (!filesToAdd.isNull()) { + performAdditions(vcs, new ArrayList<>(filesToAdd.get())); + } + } + } + } + + private static void performAdditions(@NotNull AbstractVcs vcs, + @NotNull List value) { + CheckinEnvironment checkinEnvironment = vcs.getCheckinEnvironment(); + if (checkinEnvironment != null) { + checkinEnvironment.scheduleUnversionedFilesForAddition(value); + } + } }