aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMihael Vrbanec2010-02-17 07:56:22 (EST)
committerStefan Lay2010-02-17 07:56:22 (EST)
commit8e5dd91534d9ff876d380c1c77e74aa543f30e93 (patch)
tree234019a2232c510016b2f439d040bc93737e200e
parent12172bcd4b9aa98b423bcfb5eab3940e63e53a97 (diff)
downloadegit-8e5dd91534d9ff876d380c1c77e74aa543f30e93.zip
egit-8e5dd91534d9ff876d380c1c77e74aa543f30e93.tar.gz
egit-8e5dd91534d9ff876d380c1c77e74aa543f30e93.tar.bz2
Implement "Compare with Revision" feature in history view.refs/changes/22/122/5
When a user double-clicks on an entry in the CommitGraphTable the selected file is compared with the working tree. Stefan added handling for the case that the file is not contained in the commit. Signed-off-by: Mihael Vrbanec <vrbanec@schneide.com> Signed-off-by: Stefan Lay <stefan.lay@sap.com> Change-Id: Ib3f979bd17875a9bf6e424b29ad85b00838cc3d9
-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/GitCompareFileRevisionEditorInput.java5
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java6
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java182
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties1
5 files changed, 178 insertions, 19 deletions
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 6b8943f..b09624d 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
@@ -108,6 +108,9 @@ public class UIText extends NLS {
public static String GitCloneWizard_errorCannotCreate;
/** */
+ public static String GitHistoryPage_FileNotInCommit;
+
+ /** */
public static String GitProjectPropertyPage_LabelBranch;
/** */
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitCompareFileRevisionEditorInput.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitCompareFileRevisionEditorInput.java
index b043f05..9ef715a 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitCompareFileRevisionEditorInput.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitCompareFileRevisionEditorInput.java
@@ -239,11 +239,16 @@ public class GitCompareFileRevisionEditorInput extends SaveableCompareEditorInpu
} else if (getResource(input) != null) {
String label = NLS.bind(TeamUIMessages.CompareFileRevisionEditorInput_workspace, new Object[]{ input.getLeft().getName() });
cc.setLeftLabel(label);
+ } else {
+ cc.setLeftLabel(left.getName());
}
if (getRightRevision() != null) {
String rightLabel = getFileRevisionLabel(getRightRevision());
cc.setRightLabel(rightLabel);
+ } else {
+ cc.setRightLabel(right.getName());
}
+
}
private String getFileRevisionLabel(FileRevisionTypedElement element) {
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java
index e8b2158..60ee18b 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java
@@ -229,11 +229,11 @@ class CommitGraphTable {
}
/**
- * Returns the SWT Table that backs this CommitGraphTable.
+ * Returns the SWT TableView of this CommitGraphTable.
*
* @return Table the SWT Table
*/
- public Table getTable() {
- return table.getTable();
+ public TableViewer getTableView() {
+ return table;
}
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java
index f9db277..face541 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java
@@ -13,6 +13,10 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import org.eclipse.compare.CompareEditorInput;
+import org.eclipse.compare.CompareUI;
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
@@ -21,11 +25,14 @@ import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.egit.core.ResourceList;
+import org.eclipse.egit.core.internal.storage.GitFileRevision;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIIcons;
import org.eclipse.egit.ui.UIPreferences;
import org.eclipse.egit.ui.UIText;
+import org.eclipse.egit.ui.internal.EditableRevision;
+import org.eclipse.egit.ui.internal.GitCompareFileRevisionEditorInput;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
@@ -35,47 +42,61 @@ import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.ITextOperationTarget;
+import org.eclipse.jface.util.OpenStrategy;
+import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.IndexChangedEvent;
+import org.eclipse.jgit.lib.RefsChangedEvent;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.RepositoryListener;
+import org.eclipse.jgit.revplot.PlotCommit;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevFlag;
+import org.eclipse.jgit.revwalk.RevSort;
+import org.eclipse.jgit.revwalk.filter.RevFilter;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
+import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
+import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
+import org.eclipse.team.core.history.IFileRevision;
+import org.eclipse.team.internal.ui.IPreferenceIds;
+import org.eclipse.team.internal.ui.TeamUIPlugin;
import org.eclipse.team.ui.history.HistoryPage;
+import org.eclipse.team.ui.synchronize.SaveableCompareEditorInput;
import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IReusableEditor;
import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
-import org.eclipse.jgit.lib.AnyObjectId;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.IndexChangedEvent;
-import org.eclipse.jgit.lib.RefsChangedEvent;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.lib.RepositoryListener;
-import org.eclipse.jgit.revplot.PlotCommit;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevFlag;
-import org.eclipse.jgit.revwalk.RevSort;
-import org.eclipse.jgit.revwalk.filter.RevFilter;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
-import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
-import org.eclipse.jgit.treewalk.filter.TreeFilter;
/** Graphical commit history viewer. */
public class GitHistoryPage extends HistoryPage implements RepositoryListener {
@@ -308,6 +329,50 @@ public class GitHistoryPage extends HistoryPage implements RepositoryListener {
graphDetailSplit.setLayoutData(gd);
graph = new CommitGraphTable(graphDetailSplit);
+ graph.getTableView().addOpenListener(new IOpenListener() {
+ public void open(OpenEvent event) {
+ final Object input = getInput();
+ // if multiple resources (IResourceList) or something not a file is selected we do nothing
+ if (!(input instanceof IFile)) {
+ return;
+ }
+ final IFile resource = (IFile) input;
+ final RepositoryMapping mapping = RepositoryMapping.getMapping(resource.getProject());
+ final String gitPath = mapping.getRepoRelativePath(resource);
+ IStructuredSelection selection = (IStructuredSelection) event.getSelection();
+ SWTCommit commit = (SWTCommit) selection.getFirstElement();
+ ITypedElement right = getEditableRevision(resource, gitPath,
+ commit);
+ final GitCompareFileRevisionEditorInput in = new GitCompareFileRevisionEditorInput(
+ SaveableCompareEditorInput.createFileElement(resource),
+ right,
+ null);
+ openInCompare(in);
+ }
+
+ private ITypedElement getEditableRevision(final IFile resource,
+ final String gitPath, SWTCommit commit) {
+ ITypedElement right = new EmptyElement(NLS.bind(UIText.GitHistoryPage_FileNotInCommit,
+ resource.getName(), commit));
+
+ try {
+ TreeWalk w = TreeWalk.forPath(db, gitPath, commit.getTree());
+ // check if file is contained in commit
+ if (w != null) {
+ final IFileRevision nextFile = GitFileRevision.inCommit(
+ db,
+ commit,
+ gitPath,
+ null);
+ right = new EditableRevision(nextFile);
+ }
+ } catch (IOException e) {
+ Activator.error("IO error looking up path" + gitPath + " in "
+ + commit.getId() + ".", e);
+ }
+ return right;
+ }
+ });
revInfoSplit = new SashForm(graphDetailSplit, SWT.HORIZONTAL);
commentViewer = new CommitMessageViewer(revInfoSplit);
fileViewer = new CommitFileDiffViewer(revInfoSplit);
@@ -333,6 +398,70 @@ public class GitHistoryPage extends HistoryPage implements RepositoryListener {
Repository.addAnyRepositoryChangedListener(this);
}
+ private void openInCompare(CompareEditorInput input) {
+ IWorkbenchPage workBenchPage = getSite().getPage();
+ IEditorPart editor = findReusableCompareEditor(input, workBenchPage);
+ if (editor != null) {
+ IEditorInput otherInput = editor.getEditorInput();
+ if (otherInput.equals(input)) {
+ // simply provide focus to editor
+ if (OpenStrategy.activateOnOpen())
+ workBenchPage.activate(editor);
+ else
+ workBenchPage.bringToTop(editor);
+ } else {
+ // if editor is currently not open on that input either re-use
+ // existing
+ CompareUI.reuseCompareEditor(input, (IReusableEditor) editor);
+ if (OpenStrategy.activateOnOpen())
+ workBenchPage.activate(editor);
+ else
+ workBenchPage.bringToTop(editor);
+ }
+ } else {
+ CompareUI.openCompareEditor(input);
+ }
+ }
+
+ /**
+ * Returns an editor that can be re-used. An open compare editor that
+ * has un-saved changes cannot be re-used.
+ * @param input the input being opened
+ * @param page
+ * @return an EditorPart or <code>null</code> if none can be found
+ */
+ private IEditorPart findReusableCompareEditor(CompareEditorInput input, IWorkbenchPage page) {
+ IEditorReference[] editorRefs = page.getEditorReferences();
+ // first loop looking for an editor with the same input
+ for (int i = 0; i < editorRefs.length; i++) {
+ IEditorPart part = editorRefs[i].getEditor(false);
+ if (part != null
+ && (part.getEditorInput() instanceof GitCompareFileRevisionEditorInput)
+ && part instanceof IReusableEditor
+ && part.getEditorInput().equals(input)) {
+ return part;
+ }
+ }
+ // if none found and "Reuse open compare editors" preference is on use
+ // a non-dirty editor
+ if (isReuseOpenEditor()) {
+ for (int i = 0; i < editorRefs.length; i++) {
+ IEditorPart part = editorRefs[i].getEditor(false);
+ if (part != null
+ && (part.getEditorInput() instanceof SaveableCompareEditorInput)
+ && part instanceof IReusableEditor && !part.isDirty()) {
+ return part;
+ }
+ }
+ }
+ // no re-usable editor found
+ return null;
+ }
+
+ private static boolean isReuseOpenEditor() {
+ return TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.REUSE_OPEN_COMPARE_EDITOR);
+ }
+
private Runnable refschangedRunnable;
public void refsChanged(final RefsChangedEvent e) {
@@ -808,7 +937,7 @@ public class GitHistoryPage extends HistoryPage implements RepositoryListener {
public void run() {
if (!graph.getControl().isDisposed() && job == j) {
graph.setInput(highlightFlag, list, asArray);
- findToolbar.setInput(highlightFlag, graph.getTable(),
+ findToolbar.setInput(highlightFlag, graph.getTableView().getTable(),
asArray);
}
}
@@ -856,6 +985,27 @@ public class GitHistoryPage extends HistoryPage implements RepositoryListener {
return getName();
}
+ private class EmptyElement implements ITypedElement{
+
+ private String name;
+
+ public EmptyElement(String name) {
+ this.name = name;
+ }
+
+ public Image getImage() {
+ return null;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getType() {
+ return null;
+ }
+ };
+
private abstract class BooleanPrefAction extends Action implements
IPropertyChangeListener, ActionFactory.IWorkbenchAction {
private final String prefName;
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 a97316d..64fa5b4 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
@@ -41,6 +41,7 @@ GitCloneWizard_title=Import Git Repository
GitCloneWizard_jobName=Cloning from {0}
GitCloneWizard_failed=Git repository clone failed.
GitCloneWizard_errorCannotCreate=Cannot create directory {0}.
+GitHistoryPage_FileNotInCommit={0} not in {1}
GitProjectPropertyPage_LabelBranch=Branch:
GitProjectPropertyPage_LabelGitDir=Git directory:
GitProjectPropertyPage_LabelId=Id: