@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(); } }; }
/** * 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(), '/'); }