ApplyPatchStatus (@NotNull Collection<PatchApplier> group, @Nullable LocalChangeList targetChangeList, boolean showSuccessNotification, boolean silentAddDelete) { if (group.isEmpty()) { return ApplyPatchStatus.SUCCESS; //? } Project project = group.iterator().next().myProject; return PartialChangesUtil.computeUnderChangeListSync(project, targetChangeList, () -> { ApplyPatchStatus result = ApplyPatchStatus.SUCCESS; for (PatchApplier patchApplier : group) { result = ApplyPatchStatus.and(result, patchApplier.nonWriteActionPreCheck()); } final Label beforeLabel = LocalHistory.getInstance().putSystemLabel(project, VcsBundle.message("patch.apply.before.patch.label.text")); final TriggerAdditionOrDeletion trigger = new TriggerAdditionOrDeletion(project); final Ref<ApplyPatchStatus> refStatus = new Ref<>(result); ApplicationManager.getApplication().invokeAndWait(() -> { try { runWithDefaultConfirmations(project, silentAddDelete, () -> { CommandProcessor.getInstance().executeCommand(project, () -> { List<FilePath> toBeAdded = new ArrayList<>(); List<FilePath> toBeDeleted = new ArrayList<>(); for (PatchApplier applier : group) { refStatus.set(ApplyPatchStatus.and(refStatus.get(), applier.createFiles())); toBeAdded.addAll(applier.myVerifier.getToBeAdded()); toBeDeleted.addAll(applier.myVerifier.getToBeDeleted()); } trigger.prepare(toBeAdded, toBeDeleted); if (refStatus.get() == ApplyPatchStatus.SUCCESS) { // all pre-check results are valuable only if not successful; actual status we can receive after executeWritable refStatus.set(null); } for (PatchApplier applier : group) { refStatus.set(ApplyPatchStatus.and(refStatus.get(), applier.executeWritable())); if (refStatus.get() == ApplyPatchStatus.ABORT) { break; } } }, VcsBundle.message("patch.apply.command"), null); }); } finally { trigger.cleanup(); LocalHistory.getInstance().putSystemLabel(project, VcsBundle.message("patch.apply.after.patch.label.text")); } }); result = refStatus.get(); result = result == null ? ApplyPatchStatus.FAILURE : result; trigger.processIt(); boolean rollback = false; if (result == ApplyPatchStatus.FAILURE) { rollback = askToRollback(project, group); } if (result == ApplyPatchStatus.ABORT || rollback) { rollbackUnderProgressIfNeeded(project, beforeLabel); } if (showSuccessNotification || !ApplyPatchStatus.SUCCESS.equals(result)) { showApplyStatus(project, result); } Set<FilePath> directlyAffected = new HashSet<>(); Set<VirtualFile> indirectlyAffected = new HashSet<>(); for (PatchApplier applier : group) { directlyAffected.addAll(applier.getDirectlyAffected()); indirectlyAffected.addAll(applier.getIndirectlyAffected()); } directlyAffected.addAll(trigger.getAffected()); refreshPassedFiles(project, directlyAffected, indirectlyAffected); return result; }); }