@NotNull
 private static FilePath rebasePath(
     @NotNull FilePath oldBase, @NotNull FilePath newBase, @NotNull FilePath path) {
   String relativePath =
       ObjectUtils.assertNotNull(FileUtil.getRelativePath(oldBase.getPath(), path.getPath(), '/'));
   return VcsUtil.getFilePath(newBase.getPath() + "/" + relativePath, path.isDirectory());
 }
 public ThreeState haveChangesUnder(@NotNull VirtualFile virtualFile) {
   FilePath dir = VcsUtil.getFilePath(virtualFile);
   FilePath changeCandidate = myIdx.getAffectedPaths().ceiling(dir);
   if (changeCandidate == null) {
     return ThreeState.NO;
   }
   return FileUtil.isAncestorThreeState(dir.getPath(), changeCandidate.getPath(), false);
 }
 private static SimpleDiffRequest createBinaryDiffRequest(
     final Project project, final Change change) throws VcsException {
   final FilePath filePath = ChangesUtil.getFilePath(change);
   final SimpleDiffRequest request = new SimpleDiffRequest(project, filePath.getPath());
   try {
     request.setContents(
         createBinaryFileContent(project, change.getBeforeRevision(), filePath.getName()),
         createBinaryFileContent(project, change.getAfterRevision(), filePath.getName()));
     return request;
   } catch (IOException e) {
     throw new VcsException(e);
   }
 }
 @Nullable
 private VcsRevisionNumber getCurrentRevision(FilePath file) {
   if (file.isNonLocal()) {
     // technically, it does not make sense, since there's no "current" revision for non-local
     // history (if look how it's used)
     // but ok, lets keep it for now
     return new SvnRevisionNumber(SVNRevision.HEAD);
   }
   try {
     SVNWCClient wcClient = myVcs.createWCClient();
     SVNInfo info =
         wcClient.doInfo(new File(file.getPath()).getAbsoluteFile(), SVNRevision.UNDEFINED);
     if (info != null) {
       return new SvnRevisionNumber(info.getRevision());
     } else {
       return null;
     }
   } catch (SVNException e) {
     return null;
   }
 }
 public FileHistorySessionPartner(
     final VcsHistoryProvider vcsHistoryProvider,
     @NotNull final FilePath path,
     final AbstractVcs vcs,
     final FileHistoryRefresherI refresherI) {
   myVcsHistoryProvider = vcsHistoryProvider;
   myPath = path;
   myLimitHistoryCheck = new LimitHistoryCheck(vcs.getProject(), path.getPath());
   myVcs = vcs;
   myRefresherI = refresherI;
   Consumer<List<VcsFileRevision>> sessionRefresher =
       new Consumer<List<VcsFileRevision>>() {
         public void consume(List<VcsFileRevision> vcsFileRevisions) {
           // TODO: Logic should be revised to we could just append some revisions to history panel
           // instead of creating and showing new history
           // TODO: session
           mySession.getRevisionList().addAll(vcsFileRevisions);
           final VcsHistorySession copy = mySession.copyWithCachedRevision();
           ApplicationManager.getApplication()
               .invokeLater(
                   new Runnable() {
                     public void run() {
                       ensureHistoryPanelCreated().getHistoryPanelRefresh().consume(copy);
                     }
                   });
         }
       };
   myBuffer =
       new BufferedListConsumer<VcsFileRevision>(5, sessionRefresher, 1000) {
         @Override
         protected void invokeConsumer(@NotNull Runnable consumerRunnable) {
           // Do not invoke in arbitrary background thread as due to parallel execution this could
           // lead to cases when invokeLater() (from
           // sessionRefresher) is scheduled at first for history session with (as an example) 10
           // revisions (new buffered list) and then with
           // 5 revisions (previous buffered list). And so incorrect UI is shown to the user.
           consumerRunnable.run();
         }
       };
 }
示例#6
0
 /**
  * Sort files by vcs root
  *
  * @param files files to sort.
  * @param ignoreNonGit if true, non-git files are ignored
  * @return the map from root to the files under the root
  * @throws VcsException if non git files are passed when {@code ignoreNonGit} is false
  */
 @NotNull
 public static Map<VirtualFile, List<FilePath>> sortFilePathsByGitRoot(
     @NotNull Collection<FilePath> files, boolean ignoreNonGit) throws VcsException {
   Map<VirtualFile, List<FilePath>> rc = new HashMap<VirtualFile, List<FilePath>>();
   for (FilePath p : files) {
     VirtualFile root = getGitRootOrNull(p);
     if (root == null) {
       if (ignoreNonGit) {
         continue;
       } else {
         throw new VcsException("The file " + p.getPath() + " is not under Git");
       }
     }
     List<FilePath> l = rc.get(root);
     if (l == null) {
       l = new ArrayList<FilePath>();
       rc.put(root, l);
     }
     l.add(p);
   }
   return rc;
 }
 private void collectLogEntriesForRepository(
     final ProgressIndicator indicator,
     FilePath file,
     final Consumer<VcsFileRevision> result,
     final Ref<Boolean> supports15Ref)
     throws SVNException, VcsException {
   final String url = file.getPath().replace('\\', '/');
   if (indicator != null) {
     indicator.setText2(SvnBundle.message("progress.text2.changes.establishing.connection", url));
   }
   SVNWCClient wcClient = myVcs.createWCClient();
   final SVNURL svnurl = SVNURL.parseURIEncoded(url);
   SVNInfo info = wcClient.doInfo(svnurl, SVNRevision.UNDEFINED, SVNRevision.HEAD);
   final String root = info.getRepositoryRootURL().toString();
   String relativeUrl = url;
   if (url.startsWith(root)) {
     relativeUrl = url.substring(root.length());
   }
   SVNLogClient client = myVcs.createLogClient();
   final boolean supports15 = SvnUtil.checkRepositoryVersion15(myVcs, root);
   supports15Ref.set(supports15);
   // todo log in history provider
   client.doLog(
       svnurl,
       new String[] {},
       SVNRevision.UNDEFINED,
       SVNRevision.HEAD,
       SVNRevision.create(1),
       false,
       true,
       supports15,
       0,
       null,
       new RepositoryLogEntryHandler(
           myVcs, url, SVNRevision.UNDEFINED, relativeUrl, result, info.getRepositoryRootURL()));
 }
 @NonNls
 public String toString() {
   return myFile.getPath();
 }
 public List<VcsException> commit(
     @NotNull List<Change> changes,
     @NotNull String message,
     @NotNull NullableFunction<Object, Object> parametersHolder,
     Set<String> feedback) {
   List<VcsException> exceptions = new ArrayList<VcsException>();
   Map<VirtualFile, Collection<Change>> sortedChanges = sortChangesByGitRoot(changes, exceptions);
   log.assertTrue(
       !sortedChanges.isEmpty(), "Trying to commit an empty list of changes: " + changes);
   for (Map.Entry<VirtualFile, Collection<Change>> entry : sortedChanges.entrySet()) {
     final VirtualFile root = entry.getKey();
     try {
       File messageFile = createMessageFile(root, message);
       try {
         final Set<FilePath> added = new HashSet<FilePath>();
         final Set<FilePath> removed = new HashSet<FilePath>();
         for (Change change : entry.getValue()) {
           switch (change.getType()) {
             case NEW:
             case MODIFICATION:
               added.add(change.getAfterRevision().getFile());
               break;
             case DELETED:
               removed.add(change.getBeforeRevision().getFile());
               break;
             case MOVED:
               FilePath afterPath = change.getAfterRevision().getFile();
               FilePath beforePath = change.getBeforeRevision().getFile();
               added.add(afterPath);
               if (!GitFileUtils.shouldIgnoreCaseChange(
                   afterPath.getPath(), beforePath.getPath())) {
                 removed.add(beforePath);
               }
               break;
             default:
               throw new IllegalStateException("Unknown change type: " + change.getType());
           }
         }
         try {
           try {
             Set<FilePath> files = new HashSet<FilePath>();
             files.addAll(added);
             files.addAll(removed);
             commit(
                 myProject,
                 root,
                 files,
                 messageFile,
                 myNextCommitAuthor,
                 myNextCommitAmend,
                 myNextCommitAuthorDate);
           } catch (VcsException ex) {
             PartialOperation partialOperation = isMergeCommit(ex);
             if (partialOperation == PartialOperation.NONE) {
               throw ex;
             }
             if (!mergeCommit(
                 myProject,
                 root,
                 added,
                 removed,
                 messageFile,
                 myNextCommitAuthor,
                 exceptions,
                 partialOperation)) {
               throw ex;
             }
           }
         } finally {
           if (!messageFile.delete()) {
             log.warn("Failed to remove temporary file: " + messageFile);
           }
         }
       } catch (VcsException e) {
         exceptions.add(e);
       }
     } catch (IOException ex) {
       //noinspection ThrowableInstanceNeverThrown
       exceptions.add(new VcsException("Creation of commit message file failed", ex));
     }
   }
   if (myNextCommitIsPushed != null
       && myNextCommitIsPushed.booleanValue()
       && exceptions.isEmpty()) {
     // push
     UIUtil.invokeLaterIfNeeded(
         new Runnable() {
           public void run() {
             GitPusher.showPushDialogAndPerformPush(
                 myProject, ServiceManager.getService(myProject, GitPlatformFacade.class));
           }
         });
   }
   return exceptions;
 }
  /**
   * Invokes {@link com.intellij.openapi.diff.DiffManager#getDiffTool()} to show difference between
   * the given revisions of the given file.
   *
   * @param project project under vcs control.
   * @param filePath file which revisions are compared.
   * @param revision1 first revision - 'before', to the left.
   * @param revision2 second revision - 'after', to the right.
   * @throws com.intellij.openapi.vcs.VcsException
   * @throws java.io.IOException
   */
  public static void showDiff(
      @NotNull final Project project,
      @NotNull FilePath filePath,
      @NotNull VcsFileRevision revision1,
      @NotNull VcsFileRevision revision2,
      @NotNull String title1,
      @NotNull String title2)
      throws VcsException, IOException {
    final byte[] content1 = loadRevisionContent(revision1);
    final byte[] content2 = loadRevisionContent(revision2);

    final SimpleDiffRequest diffData = new SimpleDiffRequest(project, filePath.getPresentableUrl());
    diffData.addHint(DiffTool.HINT_SHOW_FRAME);
    final Document doc = filePath.getDocument();
    final Charset charset = filePath.getCharset();
    final FileType fileType = filePath.getFileType();
    diffData.setContentTitles(title1, title2);
    final Ref<VirtualFile> f1 = new Ref<VirtualFile>(null);
    final Ref<VirtualFile> f2 = new Ref<VirtualFile>(null);

    if (fileType.isBinary()) {
      final File file1 =
          FileUtil.createTempFile(revision1.getRevisionNumber().asString(), filePath.getName());
      final File file2 =
          FileUtil.createTempFile(revision2.getRevisionNumber().asString(), filePath.getName());
      try {
        final FileOutputStream fos1 = new FileOutputStream(file1);
        fos1.write(content1);
        final FileOutputStream fos2 = new FileOutputStream(file2);
        fos2.write(content2);
        fos1.close();
        fos2.close();
        f1.set(LocalFileSystem.getInstance().findFileByIoFile(file1));
        f2.set(LocalFileSystem.getInstance().findFileByIoFile(file2));
      } catch (Exception e) { //
      }
    }
    if (f1.isNull() || f2.isNull()) {
      diffData.setContents(
          createContent(project, content1, revision1, doc, charset, fileType, filePath.getPath()),
          createContent(project, content2, revision2, doc, charset, fileType, filePath.getPath()));
    } else {
      diffData.setContents(
          createFileContent(project, f1.get(), revision1),
          createFileContent(project, f2.get(), revision2));
    }
    WaitForProgressToShow.runOrInvokeLaterAboveProgress(
        new Runnable() {
          public void run() {
            DiffManager.getInstance().getDiffTool().show(diffData);
            if (!f1.isNull() || !f2.isNull()) {
              Disposer.register(
                  project,
                  new Disposable() {
                    @Override
                    public void dispose() {
                      ApplicationManager.getApplication()
                          .runWriteAction(
                              new Runnable() {
                                public void run() {
                                  try {
                                    if (!f1.isNull()) {
                                      f1.get().delete(this);
                                    }
                                    if (!f2.isNull()) {
                                      f2.get().delete(this);
                                    }
                                  } catch (IOException e) { //
                                  }
                                }
                              });
                    }
                  });
            }
          }
        },
        null,
        project);
  }
 @Override
 protected void putParentPathImpl(Object value, String parentPath, FilePath self) {
   append(self.getPath(), SimpleTextAttributes.GRAYED_ATTRIBUTES);
 }
  private void handleComments(final DiffPanelImpl diffPanel, final String filePathString) {
    final FilePath filePath = new FilePathImpl(new File(filePathString), false);
    final String relativeFilePath =
        PathUtils.ensureSlashSeparators(getRelativeOrAbsolutePath(project, filePath.getPath()));

    addCommentAction(diffPanel, relativeFilePath, changeInfo);

    gerritUtil.getChangeDetails(
        changeInfo._number,
        project,
        new Consumer<ChangeInfo>() {
          @Override
          public void consume(ChangeInfo changeDetails) {
            gerritUtil.getComments(
                changeDetails.id,
                selectedRevisionId,
                project,
                true,
                true,
                new Consumer<Map<String, List<CommentInfo>>>() {
                  @Override
                  public void consume(Map<String, List<CommentInfo>> comments) {
                    List<CommentInfo> fileComments = comments.get(relativeFilePath);
                    if (fileComments != null) {
                      addCommentsGutter(
                          diffPanel.getEditor2(),
                          relativeFilePath,
                          selectedRevisionId,
                          Iterables.filter(fileComments, REVISION_COMMENT));
                      if (!baseRevision.isPresent()) {
                        addCommentsGutter(
                            diffPanel.getEditor1(),
                            relativeFilePath,
                            selectedRevisionId,
                            Iterables.filter(fileComments, Predicates.not(REVISION_COMMENT)));
                      }
                    }
                  }
                });

            if (baseRevision.isPresent()) {
              gerritUtil.getComments(
                  changeDetails.id,
                  baseRevision.get().getFirst(),
                  project,
                  true,
                  true,
                  new Consumer<Map<String, List<CommentInfo>>>() {
                    @Override
                    public void consume(Map<String, List<CommentInfo>> comments) {
                      List<CommentInfo> fileComments = comments.get(relativeFilePath);
                      if (fileComments != null) {
                        Collections.sort(fileComments, COMMENT_ORDERING);
                        addCommentsGutter(
                            diffPanel.getEditor1(),
                            relativeFilePath,
                            baseRevision.get().getFirst(),
                            Iterables.filter(fileComments, REVISION_COMMENT));
                      }
                    }
                  });
            }

            gerritUtil.setReviewed(changeDetails.id, selectedRevisionId, relativeFilePath, project);
          }
        });
  }
 @Nullable
 private static String getRelativePath(@NotNull GitRepository repository, @NotNull FilePath path) {
   return FileUtil.getRelativePath(repository.getRoot().getPath(), path.getPath(), '/');
 }