예제 #1
0
  private <V extends FilePatch, T extends ApplyFilePatchBase<V>> ApplyPatchStatus applyList(
      final List<Pair<VirtualFile, T>> patches,
      final ApplyPatchContext context,
      ApplyPatchStatus status,
      CommitContext commiContext)
      throws IOException {
    for (Pair<VirtualFile, T> patch : patches) {
      ApplyPatchStatus patchStatus =
          ApplyPatchAction.applyOnly(
              myProject,
              patch.getSecond(),
              context,
              patch.getFirst(),
              commiContext,
              myReverseConflict,
              myLeftConflictPanelTitle,
              myRightConflictPanelTitle);

      if (patchStatus == ApplyPatchStatus.ABORT) return patchStatus;
      status = ApplyPatchStatus.and(status, patchStatus);
      if (patchStatus == ApplyPatchStatus.FAILURE) {
        myFailedPatches.add(patch.getSecond().getPatch());
        continue;
      }
      if (patchStatus != ApplyPatchStatus.SKIP) {
        myVerifier.doMoveIfNeeded(patch.getFirst());
        myRemainingPatches.remove(patch.getSecond().getPatch());
      }
    }
    return status;
  }
예제 #2
0
  @Nullable
  private ApplyPatchStatus actualApply(
      final List<Pair<VirtualFile, ApplyTextFilePatch>> textPatches,
      final List<Pair<VirtualFile, ApplyFilePatchBase<BinaryType>>> binaryPatches,
      final CommitContext commitContext) {
    final ApplyPatchContext context = new ApplyPatchContext(myBaseDirectory, 0, true, true);
    ApplyPatchStatus status;

    try {
      status = applyList(textPatches, context, null, commitContext);

      if (status == ApplyPatchStatus.ABORT) return status;

      if (myCustomForBinaries == null) {
        status = applyList(binaryPatches, context, status, commitContext);
      } else {
        ApplyPatchStatus patchStatus = myCustomForBinaries.apply(binaryPatches);
        final List<FilePatch> appliedPatches = myCustomForBinaries.getAppliedPatches();
        moveForCustomBinaries(binaryPatches, appliedPatches);

        status = ApplyPatchStatus.and(status, patchStatus);
        myRemainingPatches.removeAll(appliedPatches);
      }
    } catch (IOException e) {
      showError(myProject, e.getMessage(), true);
      return ApplyPatchStatus.ABORT;
    }
    return status;
  }
예제 #3
0
    @CalledInAwt
    public void run() {
      myRemainingPatches.addAll(myPatches);

      final ApplyPatchStatus patchStatus = nonWriteActionPreCheck();
      final Label beforeLabel =
          LocalHistory.getInstance().putSystemLabel(myProject, "Before patch");
      final TriggerAdditionOrDeletion trigger = new TriggerAdditionOrDeletion(myProject);
      final ApplyPatchStatus applyStatus = getApplyPatchStatus(trigger);
      myStatus =
          ApplyPatchStatus.SUCCESS.equals(patchStatus)
              ? applyStatus
              : ApplyPatchStatus.and(patchStatus, applyStatus);
      // listeners finished, all 'legal' file additions/deletions with VCS are done
      trigger.processIt();
      LocalHistory.getInstance()
          .putSystemLabel(
              myProject, "After patch"); // insert a label to be visible in local history dialog
      if (myStatus == ApplyPatchStatus.FAILURE) {
        suggestRollback(myProject, Collections.singletonList(PatchApplier.this), beforeLabel);
      } else if (myStatus == ApplyPatchStatus.ABORT) {
        rollbackUnderProgress(myProject, myProject.getBaseDir(), beforeLabel);
      }
      if (myShowNotification || !ApplyPatchStatus.SUCCESS.equals(myStatus)) {
        showApplyStatus(myProject, myStatus);
      }
      refreshFiles(trigger.getAffected());
    }
예제 #4
0
 @Nullable
 protected ApplyPatchStatus executeWritable() {
   final ReadonlyStatusHandler.OperationStatus readOnlyFilesStatus =
       getReadOnlyFilesStatus(myVerifier.getWritableFiles());
   if (readOnlyFilesStatus.hasReadonlyFiles()) {
     showError(myProject, readOnlyFilesStatus.getReadonlyFilesMessage(), true);
     return ApplyPatchStatus.ABORT;
   }
   myFailedPatches.addAll(myVerifier.filterBadFileTypePatches());
   ApplyPatchStatus result = myFailedPatches.isEmpty() ? null : ApplyPatchStatus.FAILURE;
   final List<Pair<VirtualFile, ApplyTextFilePatch>> textPatches = myVerifier.getTextPatches();
   try {
     markInternalOperation(textPatches, true);
     return ApplyPatchStatus.and(
         result, actualApply(textPatches, myVerifier.getBinaryPatches(), myCommitContext));
   } finally {
     markInternalOperation(textPatches, false);
   }
 }
예제 #5
0
  @CalledInAwt
  public static ApplyPatchStatus executePatchGroup(
      final Collection<PatchApplier> group, final LocalChangeList localChangeList) {
    if (group.isEmpty()) return ApplyPatchStatus.SUCCESS; // ?
    final Project project = group.iterator().next().myProject;

    ApplyPatchStatus result = ApplyPatchStatus.SUCCESS;
    for (PatchApplier patchApplier : group) {
      result = ApplyPatchStatus.and(result, patchApplier.nonWriteActionPreCheck());
    }
    final Label beforeLabel = LocalHistory.getInstance().putSystemLabel(project, "Before patch");
    final TriggerAdditionOrDeletion trigger = new TriggerAdditionOrDeletion(project);
    final Ref<ApplyPatchStatus> refStatus = new Ref<>(result);
    try {
      CommandProcessor.getInstance()
          .executeCommand(
              project,
              new Runnable() {
                @Override
                public void run() {
                  for (PatchApplier applier : group) {
                    refStatus.set(ApplyPatchStatus.and(refStatus.get(), applier.createFiles()));
                    applier.addSkippedItems(trigger);
                  }
                  trigger.prepare();
                  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 {
      VcsFileListenerContextHelper.getInstance(project).clearContext();
      LocalHistory.getInstance().putSystemLabel(project, "After patch");
    }
    result = refStatus.get();
    result = result == null ? ApplyPatchStatus.FAILURE : result;

    trigger.processIt();
    final Set<FilePath> directlyAffected = new HashSet<>();
    final Set<VirtualFile> indirectlyAffected = new HashSet<>();
    for (PatchApplier applier : group) {
      directlyAffected.addAll(applier.getDirectlyAffected());
      indirectlyAffected.addAll(applier.getIndirectlyAffected());
    }
    directlyAffected.addAll(trigger.getAffected());
    final Consumer<Collection<FilePath>> mover =
        localChangeList == null ? null : createMover(project, localChangeList);
    refreshPassedFilesAndMoveToChangelist(project, directlyAffected, indirectlyAffected, mover);
    if (result == ApplyPatchStatus.FAILURE) {
      suggestRollback(project, group, beforeLabel);
    } else if (result == ApplyPatchStatus.ABORT) {
      rollbackUnderProgress(project, project.getBaseDir(), beforeLabel);
    }
    showApplyStatus(project, result);
    return result;
  }