Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Sawicki2011-11-29 21:35:59 +0000
committerStefan Lay2011-11-30 12:23:15 +0000
commit8a524f1f0802b045f8ad84b01df710002ed5fb76 (patch)
tree5d29c54f89f918c3d6ec771014d442d147e45a80
parent75a1cf972c4a501ef0a991c1346ca95e66c9eb5a (diff)
downloadegit-8a524f1f0802b045f8ad84b01df710002ed5fb76.tar.gz
egit-8a524f1f0802b045f8ad84b01df710002ed5fb76.tar.xz
egit-8a524f1f0802b045f8ad84b01df710002ed5fb76.zip
Support 'Show Annotations' on history items
Blame can now be run from the file table in the history view as well as the file section of the commit editor. The blame operation will open the file in a read-only editor and show annotations starting at the selected commit. Bug: 362052 Change-Id: I8c88d704581f50e5c406724100d7e8ee31f72701 Signed-off-by: Kevin Sawicki <kevin@github.com>
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/CommitEditorTest.java35
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java6
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java3
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ShowBlameActionHandler.java30
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameOperation.java39
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitFileDiffViewer.java54
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties1
7 files changed, 146 insertions, 22 deletions
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/CommitEditorTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/CommitEditorTest.java
index b3d77446fe..7e0e25e149 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/CommitEditorTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/CommitEditorTest.java
@@ -11,6 +11,7 @@
package org.eclipse.egit.ui.test.commit;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -18,14 +19,20 @@ import java.io.File;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.ui.UIText;
import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
import org.eclipse.egit.ui.internal.commit.CommitEditor;
import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
+import org.eclipse.egit.ui.test.ContextMenuHelper;
+import org.eclipse.egit.ui.test.TestUtil;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotMultiPageEditor;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
@@ -90,4 +97,32 @@ public class CommitEditorTest extends LocalRepositoryTestCase {
botEditor.activatePage(name);
botEditor.close();
}
+
+ @Test
+ public void showAnnotations() throws Exception {
+ final AtomicReference<IEditorPart> editorRef = new AtomicReference<IEditorPart>();
+ PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
+
+ public void run() {
+ RepositoryCommit repoCommit = new RepositoryCommit(repository,
+ commit);
+ editorRef.set(CommitEditor.openQuiet(repoCommit));
+ }
+ });
+ assertNotNull(editorRef.get());
+ SWTBotEditor commitEditor = bot.activeEditor();
+ SWTBotTable table = commitEditor.bot().table(0);
+ assertTrue(table.rowCount() > 0);
+ table.select(0);
+ ContextMenuHelper.clickContextMenu(table,
+ UIText.CommitFileDiffViewer_ShowAnnotationsMenuLabel);
+ TestUtil.joinJobs(JobFamilies.BLAME);
+ assertFalse(commitEditor.getReference().equals(
+ bot.activeEditor().getReference()));
+
+ final String content = getTestFileContent();
+ // Change working directory content to validate blame opens HEAD
+ setTestFileContent("updated content" + System.nanoTime());
+ assertEquals(content, bot.activeEditor().toTextEditor().getText());
+ }
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java
index 2a0bd886dc..923dbfbbed 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java
@@ -117,10 +117,14 @@ public class JobFamilies {
* Clone repository job
*/
public static final Object CLONE = new Object();
-
+
/**
* Fetch data from git job
*/
public static final Object SYNCHRONIZE_READ_DATA = new Object();
+ /**
+ * Show annotations git job
+ */
+ public static final Object BLAME = new Object();
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java
index c90b426e5a..e5e221d14a 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java
@@ -3347,6 +3347,9 @@ public class UIText extends NLS {
public static String CommitFileDiffViewer_SelectOneCommitMessage;
/** */
+ public static String CommitFileDiffViewer_ShowAnnotationsMenuLabel;
+
+ /** */
public static String CommitGraphTable_CommitId;
/** */
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ShowBlameActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ShowBlameActionHandler.java
index 1e0421f836..f72e96e93b 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ShowBlameActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ShowBlameActionHandler.java
@@ -12,12 +12,16 @@ package org.eclipse.egit.ui.internal.actions;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
import org.eclipse.egit.core.internal.job.JobUtil;
+import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.ui.JobFamilies;
import org.eclipse.egit.ui.UIText;
import org.eclipse.egit.ui.internal.blame.BlameOperation;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.handlers.HandlerUtil;
/**
@@ -28,13 +32,25 @@ public class ShowBlameActionHandler extends RepositoryActionHandler {
/** @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent) */
public Object execute(final ExecutionEvent event) throws ExecutionException {
IResource[] selected = getSelectedResources();
+ if (selected.length != 1 || !(selected[0] instanceof IStorage))
+ return null;
+
Repository repository = getRepository();
- if (repository != null && selected.length == 1
- && selected[0] instanceof IFile)
- JobUtil.scheduleUserJob(new BlameOperation(repository,
- (IFile) selected[0], HandlerUtil.getActiveShell(event),
- HandlerUtil.getActiveSite(event).getPage()),
- UIText.ShowBlameHandler_JobName, null);
+ if (repository == null)
+ return null;
+
+ RepositoryMapping mapping = RepositoryMapping.getMapping(selected[0]
+ .getProject());
+ if (mapping == null)
+ return null;
+
+ String path = mapping.getRepoRelativePath(selected[0]);
+ IStorage storage = (IStorage) selected[0];
+ Shell shell = HandlerUtil.getActiveShell(event);
+ IWorkbenchPage page = HandlerUtil.getActiveSite(event).getPage();
+ JobUtil.scheduleUserJob(new BlameOperation(repository, storage, path,
+ null, shell, page), UIText.ShowBlameHandler_JobName,
+ JobFamilies.BLAME);
return null;
}
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameOperation.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameOperation.java
index 618e660b22..eae0fd5a6f 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameOperation.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameOperation.java
@@ -14,17 +14,18 @@ import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.egit.core.op.IEGitOperation;
-import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIPreferences;
import org.eclipse.jface.text.revisions.RevisionInformation;
import org.eclipse.jgit.api.BlameCommand;
import org.eclipse.jgit.blame.BlameResult;
import org.eclipse.jgit.diff.RawTextComparator;
+import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.swt.widgets.Shell;
@@ -40,7 +41,11 @@ public class BlameOperation implements IEGitOperation {
private Repository repository;
- private IFile file;
+ private IStorage storage;
+
+ private String path;
+
+ private AnyObjectId startCommit;
private Shell shell;
@@ -50,14 +55,18 @@ public class BlameOperation implements IEGitOperation {
* Create annotate operation
*
* @param repository
- * @param file
+ * @param storage
+ * @param path
+ * @param startCommit
* @param shell
* @param page
*/
- public BlameOperation(Repository repository, IFile file, Shell shell,
- IWorkbenchPage page) {
+ public BlameOperation(Repository repository, IStorage storage, String path,
+ AnyObjectId startCommit, Shell shell, IWorkbenchPage page) {
this.repository = repository;
- this.file = file;
+ this.storage = storage;
+ this.path = path;
+ this.startCommit = startCommit;
this.shell = shell;
this.page = page;
}
@@ -67,14 +76,11 @@ public class BlameOperation implements IEGitOperation {
info.setHoverControlCreator(new BlameInformationControlCreator(false));
info.setInformationPresenterControlCreator(new BlameInformationControlCreator(
true));
- RepositoryMapping mapping = RepositoryMapping.getMapping(file
- .getProject());
- if (mapping == null)
- return;
final BlameCommand command = new BlameCommand(repository)
- .setFollowFileRenames(true).setFilePath(
- mapping.getRepoRelativePath(file));
+ .setFollowFileRenames(true).setFilePath(path);
+ if (startCommit != null)
+ command.setStartCommit(startCommit);
if (Activator.getDefault().getPreferenceStore()
.getBoolean(UIPreferences.BLAME_IGNORE_WHITESPACE))
command.setTextComparator(RawTextComparator.WS_IGNORE_ALL);
@@ -122,8 +128,13 @@ public class BlameOperation implements IEGitOperation {
shell.getDisplay().asyncExec(new Runnable() {
public void run() {
try {
- AbstractDecoratedTextEditor editor = RevisionAnnotationController
- .openEditor(page, file);
+ AbstractDecoratedTextEditor editor;
+ if (storage instanceof IFile)
+ editor = RevisionAnnotationController.openEditor(page,
+ (IFile) storage);
+ else
+ editor = RevisionAnnotationController.openEditor(page,
+ storage, storage);
if (editor != null)
editor.showRevisionInformation(info,
"org.eclipse.egit.ui.internal.decorators.GitQuickDiffProvider"); //$NON-NLS-1$
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitFileDiffViewer.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitFileDiffViewer.java
index a801e20a52..ee95fdc090 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitFileDiffViewer.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitFileDiffViewer.java
@@ -16,13 +16,17 @@ import org.eclipse.compare.ITypedElement;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.internal.job.JobUtil;
import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.ui.UIIcons;
import org.eclipse.egit.ui.UIPreferences;
import org.eclipse.egit.ui.UIText;
import org.eclipse.egit.ui.UIUtils;
import org.eclipse.egit.ui.internal.CompareUtils;
import org.eclipse.egit.ui.internal.EgitUiEditorUtils;
import org.eclipse.egit.ui.internal.GitCompareFileRevisionEditorInput;
+import org.eclipse.egit.ui.internal.blame.BlameOperation;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.MenuManager;
@@ -86,6 +90,8 @@ public class CommitFileDiffViewer extends TableViewer {
private IAction open;
+ private IAction blame;
+
private IAction openWorkingTreeVersion;
private IAction compare;
@@ -194,6 +200,21 @@ public class CommitFileDiffViewer extends TableViewer {
}
};
+ blame = new Action(
+ UIText.CommitFileDiffViewer_ShowAnnotationsMenuLabel,
+ UIIcons.ANNOTATE) {
+ @SuppressWarnings("unchecked")
+ @Override
+ public void run() {
+ final ISelection s = getSelection();
+ if (s.isEmpty() || !(s instanceof IStructuredSelection))
+ return;
+ final IStructuredSelection iss = (IStructuredSelection) s;
+ for (Iterator<FileDiff> it = iss.iterator(); it.hasNext();)
+ showAnnotations(it.next());
+ }
+ };
+
openWorkingTreeVersion = new Action(
UIText.CommitFileDiffViewer_OpenWorkingTreeVersionInEditorMenuLabel) {
@SuppressWarnings("unchecked")
@@ -237,6 +258,7 @@ public class CommitFileDiffViewer extends TableViewer {
mgr.add(open);
mgr.add(openWorkingTreeVersion);
mgr.add(compare);
+ mgr.add(blame);
mgr.add(new Separator());
mgr.add(selectAll = createStandardAction(ActionFactory.SELECT_ALL));
@@ -366,6 +388,38 @@ public class CommitFileDiffViewer extends TableViewer {
}
}
+ private void showAnnotations(FileDiff d) {
+ try {
+ IWorkbenchWindow window = PlatformUI.getWorkbench()
+ .getActiveWorkbenchWindow();
+ IWorkbenchPage page = window.getActivePage();
+ RevCommit commit = d.getChange().equals(ChangeType.DELETE) ? d
+ .getCommit().getParent(0) : d.getCommit();
+ IFileRevision rev = CompareUtils.getFileRevision(d.getPath(),
+ commit, getRepository(),
+ d.getChange().equals(ChangeType.DELETE) ? d.getBlobs()[0]
+ : d.getBlobs()[d.getBlobs().length - 1]);
+ if (rev != null) {
+ BlameOperation op = new BlameOperation(getRepository(),
+ rev.getStorage(new NullProgressMonitor()), d.getPath(),
+ commit, window.getShell(), page);
+ JobUtil.scheduleUserJob(op, UIText.ShowBlameHandler_JobName,
+ JobFamilies.BLAME);
+ } else {
+ String message = NLS.bind(
+ UIText.CommitFileDiffViewer_notContainedInCommit,
+ d.getPath(), d.getCommit().getId().getName());
+ Activator.showError(message, null);
+ }
+ } catch (IOException e) {
+ Activator.logError(UIText.GitHistoryPage_openFailed, e);
+ Activator.showError(UIText.GitHistoryPage_openFailed, null);
+ } catch (CoreException e) {
+ Activator.logError(UIText.GitHistoryPage_openFailed, e);
+ Activator.showError(UIText.GitHistoryPage_openFailed, null);
+ }
+ }
+
void showTwoWayFileDiff(final FileDiff d) {
final GitCompareFileRevisionEditorInput in;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
index 84ccf2b0f4..4844b83183 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
@@ -1174,6 +1174,7 @@ CommitFileDiffViewer_notContainedInCommit=File {0} is not contained in commit {1
CommitFileDiffViewer_OpenInEditorMenuLabel=Open in &Editor
CommitFileDiffViewer_OpenWorkingTreeVersionInEditorMenuLabel=Open Working Tree Version
CommitFileDiffViewer_SelectOneCommitMessage=Please select exactly one commit
+CommitFileDiffViewer_ShowAnnotationsMenuLabel=Show Annotations
CommitGraphTable_CommitId=Id
CommitGraphTable_Committer=Committer
CommitGraphTable_CompareWithEachOtherInTreeMenuLabel=Compare with Each Other in &Tree

Back to the top