diff --git a/platform/lang-impl/src/com/intellij/unscramble/AnnotateStackTraceAction.java b/platform/lang-impl/src/com/intellij/unscramble/AnnotateStackTraceAction.java index 450b82e3cddc..42b1ef5e79be 100644 --- a/platform/lang-impl/src/com/intellij/unscramble/AnnotateStackTraceAction.java +++ b/platform/lang-impl/src/com/intellij/unscramble/AnnotateStackTraceAction.java @@ -37,6 +37,7 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.VcsException; @@ -46,15 +47,13 @@ import com.intellij.openapi.vcs.actions.VcsContextFactory; import com.intellij.openapi.vcs.annotate.AnnotationSource; import com.intellij.openapi.vcs.annotate.ShowAllAffectedGenericAction; import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx; -import com.intellij.openapi.vcs.history.VcsFileRevision; -import com.intellij.openapi.vcs.history.VcsHistoryProvider; -import com.intellij.openapi.vcs.history.VcsHistorySession; -import com.intellij.openapi.vcs.history.VcsRevisionNumber; +import com.intellij.openapi.vcs.history.*; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.text.DateFormatUtil; import com.intellij.vcsUtil.VcsUtil; import com.intellij.xml.util.XmlStringUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.awt.*; import java.util.*; @@ -65,7 +64,7 @@ import java.util.List; */ public class AnnotateStackTraceAction extends AnAction implements DumbAware { private final EditorHyperlinkSupport myHyperlinks; - private Map cache; + private Map cache; private int newestLine = -1; private int maxDateLength = 0; private final Editor myEditor; @@ -81,8 +80,8 @@ public class AnnotateStackTraceAction extends AnAction implements DumbAware { } @Override - public void actionPerformed(AnActionEvent e) { - cache = new HashMap(); + public void actionPerformed(final AnActionEvent e) { + cache = new HashMap(); ProgressManager.getInstance().run( new Task.Backgroundable(myEditor.getProject(), "Getting file history", true, PerformInBackgroundOption.ALWAYS_BACKGROUND) { @@ -99,7 +98,7 @@ public class AnnotateStackTraceAction extends AnAction implements DumbAware { final EditorGutterAction action = new EditorGutterAction() { @Override public void doAction(int lineNum) { - final VcsFileRevision revision = cache.get(lineNum); + final LastRevision revision = cache.get(lineNum); final List links = myHyperlinks.findAllHyperlinksOnLine(lineNum); if (!links.isEmpty()) { final RangeHighlighter key = links.get(links.size() - 1); @@ -110,7 +109,7 @@ public class AnnotateStackTraceAction extends AnAction implements DumbAware { final Project project = getProject(); final AbstractVcs vcs = ProjectLevelVcsManagerEx.getInstanceEx(project).getVcsFor(file); if (vcs != null) { - final VcsRevisionNumber number = revision.getRevisionNumber(); + final VcsRevisionNumber number = revision.getNumber(); final VcsKey vcsKey = vcs.getKeyInstanceMethod(); ShowAllAffectedGenericAction.showSubmittedFiles(project, number, file, vcsKey); } @@ -136,23 +135,23 @@ public class AnnotateStackTraceAction extends AnAction implements DumbAware { @Override public String getLineText(int line, Editor editor) { - final VcsFileRevision revision = cache.get(line); + final LastRevision revision = cache.get(line); if (revision != null) { - return String.format("%"+maxDateLength+"s", DateFormatUtil.formatPrettyDate(revision.getRevisionDate())) + " " + revision.getAuthor(); + return String.format("%"+maxDateLength+"s", DateFormatUtil.formatPrettyDate(revision.getDate())) + " " + revision.getAuthor(); } return ""; } @Override public String getToolTip(int line, Editor editor) { - final VcsFileRevision revision = cache.get(line); + final LastRevision revision = cache.get(line); if (revision != null) { return XmlStringUtil.wrapInHtml( revision.getAuthor() + " " + - DateFormatUtil.formatDateTime(revision.getRevisionDate()) + + DateFormatUtil.formatDateTime(revision.getDate()) + "
" + - revision.getCommitMessage() + revision.getMessage() ); } return null; @@ -218,51 +217,66 @@ public class AnnotateStackTraceAction extends AnAction implements DumbAware { for (VirtualFile file : files) { indicator.checkCanceled(); - final AbstractVcs vcs = VcsUtil.getVcsFor(myEditor.getProject(), file); - FilePath filePath = VcsContextFactory.SERVICE.getInstance().createFilePathOn(file); - if (vcs != null) { - try { - final VcsHistoryProvider provider = vcs.getVcsHistoryProvider(); - final VcsHistorySession session; - if (provider != null) { - session = provider.createSessionFor(filePath); - final List list; - if (session != null) { - list = session.getRevisionList(); - final List lines = files2lines.get(file); - if (list != null && !list.isEmpty()) { - final VcsFileRevision revision = list.get(0); - final Date date = revision.getRevisionDate(); - if (newestDate == null || date.after(newestDate)) { - newestDate = date; - newestLine = lines.get(0); - } - final int length = DateFormatUtil.formatPrettyDate(date).length(); - if (length > maxDateLength) { - maxDateLength = length; - } - for (Integer line : lines) { - cache.put(line, revision); - } - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - if (!myGutterShowed) { - showGutter(); - } else { - ((EditorGutterComponentEx)myEditor.getGutter()).revalidateMarkup(); - } - } - }); - } + + LastRevision revision = getLastRevision(file); + if (revision != null) { + final List lines = files2lines.get(file); + + final Date date = revision.getDate(); + if (newestDate == null || date.after(newestDate)) { + newestDate = date; + newestLine = lines.get(0); + } + final int length = DateFormatUtil.formatPrettyDate(date).length(); + if (length > maxDateLength) { + maxDateLength = length; + } + for (Integer line : lines) { + cache.put(line, revision); + } + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + if (!myGutterShowed) { + showGutter(); + } + else { + ((EditorGutterComponentEx)myEditor.getGutter()).revalidateMarkup(); } } - } - catch (VcsException ignored) { - ignored.printStackTrace(); - } + }); } + } + } + @Nullable + private LastRevision getLastRevision(@NotNull VirtualFile file) { + try { + final AbstractVcs vcs = VcsUtil.getVcsFor(myEditor.getProject(), file); + if (vcs == null) return null; + + VcsHistoryProvider historyProvider = vcs.getVcsHistoryProvider(); + if (historyProvider == null) return null; + + FilePath filePath = VcsContextFactory.SERVICE.getInstance().createFilePathOn(file); + + if (historyProvider instanceof VcsHistoryProviderEx) { + VcsFileRevision revision = ((VcsHistoryProviderEx)historyProvider).getLastRevision(filePath); + if (revision == null) return null; + return LastRevision.create(revision); + } else { + VcsHistorySession session = historyProvider.createSessionFor(filePath); + if (session == null) return null; + + List list = session.getRevisionList(); + if (list == null || list.isEmpty()) return null; + + return LastRevision.create(list.get(0)); + } + } + catch (VcsException ignored) { + ignored.printStackTrace(); + return null; } } }); @@ -272,4 +286,47 @@ public class AnnotateStackTraceAction extends AnAction implements DumbAware { public void update(AnActionEvent e) { e.getPresentation().setEnabled(cache == null || !myGutterShowed); } + + private static class LastRevision { + @NotNull private final VcsRevisionNumber myNumber; + @NotNull private final String myAuthor; + @NotNull private final Date myDate; + @NotNull private final String myMessage; + + public LastRevision(@NotNull VcsRevisionNumber number, @NotNull String author, @NotNull Date date, @NotNull String message) { + myNumber = number; + myAuthor = author; + myDate = date; + myMessage = message; + } + + @NotNull + public static LastRevision create(@NotNull VcsFileRevision revision) { + VcsRevisionNumber number = revision.getRevisionNumber(); + String author = StringUtil.notNullize(revision.getAuthor(), "Unknown"); + Date date = revision.getRevisionDate(); + String message = StringUtil.notNullize(revision.getCommitMessage()); + return new LastRevision(number, author, date, message); + } + + @NotNull + public VcsRevisionNumber getNumber() { + return myNumber; + } + + @NotNull + public String getAuthor() { + return myAuthor; + } + + @NotNull + public Date getDate() { + return myDate; + } + + @NotNull + public String getMessage() { + return myMessage; + } + } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryProviderEx.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryProviderEx.java new file mode 100644 index 000000000000..093cbf45185c --- /dev/null +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/VcsHistoryProviderEx.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.vcs.history; + +import com.intellij.openapi.vcs.CalledInBackground; +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.VcsException; +import org.jetbrains.annotations.Nullable; + +public interface VcsHistoryProviderEx extends VcsHistoryProvider { + @Nullable + @CalledInBackground + VcsFileRevision getLastRevision(FilePath filePath) throws VcsException; +} diff --git a/plugins/git4idea/src/git4idea/history/GitHistoryProvider.java b/plugins/git4idea/src/git4idea/history/GitHistoryProvider.java index 7550f804fb21..0d4942f2add2 100644 --- a/plugins/git4idea/src/git4idea/history/GitHistoryProvider.java +++ b/plugins/git4idea/src/git4idea/history/GitHistoryProvider.java @@ -52,7 +52,7 @@ import java.util.List; /** * Git history provider implementation */ -public class GitHistoryProvider implements VcsHistoryProvider, VcsCacheableHistorySessionFactory, +public class GitHistoryProvider implements VcsHistoryProviderEx, VcsCacheableHistorySessionFactory, VcsBaseRevisionAdviser { private static final Logger log = Logger.getInstance(GitHistoryProvider.class.getName()); @@ -139,6 +139,14 @@ public class GitHistoryProvider implements VcsHistoryProvider, VcsCacheableHisto }; } + @Nullable + @Override + public VcsFileRevision getLastRevision(FilePath filePath) throws VcsException { + List history = GitHistoryUtils.history(myProject, filePath, "--max-count=1"); + if (history == null || history.isEmpty()) return null; + return history.get(0); + } + @Override public boolean getBaseVersionContent(FilePath filePath, Processor processor, diff --git a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java index 1337735820ac..1c310492059d 100644 --- a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java +++ b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java @@ -650,9 +650,9 @@ public class GitHistoryUtils { * @return the list of the revisions * @throws VcsException if there is problem with running git */ - public static List history(final Project project, final FilePath path) throws VcsException { + public static List history(final Project project, final FilePath path, String... parameters) throws VcsException { final VirtualFile root = GitUtil.getGitRoot(path); - return history(project, path, root); + return history(project, path, root, parameters); } /**