Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wolf2019-09-22 10:58:25 -0400
committerThomas Wolf2019-09-30 16:14:10 -0400
commit0c17469b141549011d5d2f4e6731b3fab2ef4379 (patch)
treeb9052c379cfbb96a71709a7cc8ab170995458135
parenta0b9dfe131ad2046e2f4b3cfdcd60ba7c7ae81d3 (diff)
downloadegit-0c17469b141549011d5d2f4e6731b3fab2ef4379.tar.gz
egit-0c17469b141549011d5d2f4e6731b3fab2ef4379.tar.xz
egit-0c17469b141549011d5d2f4e6731b3fab2ef4379.zip
Adapt editor inputs to IFile for merge with index stage 2 as input
Otherwise the framework cannot find the correct DocumentProvider, which may cause a PartInitException on opening the merge editor. This uses the same hacks as in LocalNonWorkspaceTypedElement. Bug: 550989 Change-Id: Id024c7f849f4cc6d16e6aa4e845f04f86c9534e5 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
-rw-r--r--org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/MergeToolTest.java16
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/EditableRevision.java216
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/LocationEditableRevision.java13
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/ResourceEditableRevision.java10
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/compare/LocalNonWorkspaceTypedElement.java2
5 files changed, 181 insertions, 76 deletions
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/MergeToolTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/MergeToolTest.java
index 55a1cb612..35f2a3487 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/MergeToolTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/MergeToolTest.java
@@ -22,6 +22,7 @@ import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.JobFamilies;
import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
import org.eclipse.egit.core.op.MergeOperation;
+import org.eclipse.egit.ui.UIPreferences;
import org.eclipse.egit.ui.common.CompareEditorTester;
import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
import org.eclipse.egit.ui.test.ContextMenuHelper;
@@ -32,6 +33,7 @@ import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -42,16 +44,28 @@ public class MergeToolTest extends LocalRepositoryTestCase {
private TestRepository testRepository;
+ private int mergeMode;
+
@Before
public void setUp() throws Exception {
File repositoryFile = createProjectAndCommitToRepository();
Repository repository = lookupRepository(repositoryFile);
- testRepository = new TestRepository<Repository>(repository);
+ testRepository = new TestRepository<>(repository);
+ mergeMode = org.eclipse.egit.ui.Activator.getDefault()
+ .getPreferenceStore().getInt(UIPreferences.MERGE_MODE);
+ }
+
+ @After
+ public void resetMergeMode() throws Exception {
+ org.eclipse.egit.ui.Activator.getDefault().getPreferenceStore()
+ .setValue(UIPreferences.MERGE_MODE, mergeMode);
}
@Test
public void useHeadOptionShouldCauseFileToNotHaveConflictMarkers()
throws Exception {
+ org.eclipse.egit.ui.Activator.getDefault().getPreferenceStore()
+ .setValue(UIPreferences.MERGE_MODE, 2);
IPath path = new Path(PROJ1).append("folder/test.txt");
testRepository.branch("stable").commit().add(path.toString(), "stable")
.create();
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/EditableRevision.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/EditableRevision.java
index 07395793f..fef6ae91f 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/EditableRevision.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/EditableRevision.java
@@ -26,6 +26,7 @@ import org.eclipse.core.resources.IEncodedStorage;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
import org.eclipse.egit.core.internal.SafeRunnable;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.internal.UIText;
@@ -96,81 +97,7 @@ public class EditableRevision extends FileRevisionTypedElement implements
public IEditorInput getDocumentKey(Object element) {
if (element == this) {
if (input == null) {
- input = new IStorageEditorInput() {
-
- @Override
- public boolean exists() {
- return true;
- }
-
- @Override
- public ImageDescriptor getImageDescriptor() {
- return null;
- }
-
- @Override
- public String getName() {
- return EditableRevision.this.getName();
- }
-
- @Override
- public IPersistableElement getPersistable() {
- return null;
- }
-
- @Override
- public String getToolTipText() {
- return EditableRevision.this.getName();
- }
-
- @Override
- public <T> T getAdapter(Class<T> adapter) {
- return null;
- }
-
- private IStorage storage;
-
- @Override
- public IStorage getStorage() throws CoreException {
- if (storage == null) {
- storage = new IEncodedStorage() {
-
- @Override
- public <T> T getAdapter(Class<T> adapter) {
- return null;
- }
-
- @Override
- public boolean isReadOnly() {
- return false;
- }
-
- @Override
- public String getName() {
- return EditableRevision.this.getName();
- }
-
- @Override
- public IPath getFullPath() {
- return null;
- }
-
- @Override
- public InputStream getContents()
- throws CoreException {
- return EditableRevision.this.getContents();
- }
-
- @Override
- public String getCharset()
- throws CoreException {
- return EditableRevision.this.getCharset();
- }
- };
- }
- return storage;
- }
- };
+ input = new FakeResourceStorageEditorInput(this);
}
return input;
}
@@ -193,6 +120,20 @@ public class EditableRevision extends FileRevisionTypedElement implements
}
/**
+ * Adapt the given editor input. May be overridden in subclasses.
+ *
+ * @param editorInput
+ * of this revision
+ * @param adapter
+ * to adapt to
+ * @return the adapted object or {@code null} if none
+ */
+ protected <T> T adaptEditorInput(IEditorInput editorInput,
+ Class<T> adapter) {
+ return null;
+ }
+
+ /**
* Notifies all registered <code>IContentChangeListener</code>s of a content
* change.
*/
@@ -297,9 +238,134 @@ public class EditableRevision extends FileRevisionTypedElement implements
}
@Override
+ public void connect(IDocumentProvider provider,
+ IEditorInput documentKey) throws CoreException {
+ if (documentKey instanceof FakeResourceStorageEditorInput) {
+ // When we connect, our editor input shouldn't adapt to
+ // that (non-existing) resource, otherwise we'll confuse
+ // other parts of Eclipse.
+ FakeResourceStorageEditorInput input = (FakeResourceStorageEditorInput) documentKey;
+ try {
+ input.setAdapt(false);
+ super.connect(provider, input);
+ } finally {
+ // Once we _are_ connected, there are other places
+ // where SharedDocumentAdapter.getDocumentProvider()
+ // is called again during the life of the document,
+ // so the documentKey must again adapt to IFile.
+ input.setAdapt(true);
+ }
+ } else {
+ super.connect(provider, documentKey);
+ }
+ }
+
+ @Override
public IEditorInput getDocumentKey(Object element) {
return editable.getDocumentKey(element);
}
}
+ /**
+ * @see org.eclipse.egit.ui.internal.synchronize.compare.LocalNonWorkspaceTypedElement
+ */
+ private static class FakeResourceStorageEditorInput
+ implements IStorageEditorInput {
+
+ // This class and the connect() override above are a work-around for bug
+ // 544315: the file extension is used to find the document provider only
+ // if the editor input adapts to IFile.
+
+ // TODO: figure out a way to use a FileStoreEditorInput instead
+ // (perhaps with a little EFS to access the index). Then this hack
+ // could be removed once EGit's base platform is Eclipse 4.11
+ // (2019-03).
+
+ private final EditableRevision editable;
+
+ private boolean adapt;
+
+ public FakeResourceStorageEditorInput(EditableRevision revision) {
+ editable = revision;
+ adapt = true;
+ }
+
+ public void setAdapt(boolean adapt) {
+ this.adapt = adapt;
+ }
+
+ @Override
+ public boolean exists() {
+ return true;
+ }
+
+ @Override
+ public ImageDescriptor getImageDescriptor() {
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ return editable.getName();
+ }
+
+ @Override
+ public IPersistableElement getPersistable() {
+ return null;
+ }
+
+ @Override
+ public String getToolTipText() {
+ return editable.getName();
+ }
+
+ @Override
+ public <T> T getAdapter(Class<T> adapter) {
+ if (adapt) {
+ return editable.adaptEditorInput(this, adapter);
+ }
+ return null;
+ }
+
+ private IStorage storage;
+
+ @Override
+ public IStorage getStorage() throws CoreException {
+ if (storage == null) {
+ storage = new IEncodedStorage() {
+
+ @Override
+ public <T> T getAdapter(Class<T> adapter) {
+ return null;
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return false;
+ }
+
+ @Override
+ public String getName() {
+ return editable.getName();
+ }
+
+ @Override
+ public IPath getFullPath() {
+ return new Path(editable.getPath());
+ }
+
+ @Override
+ public InputStream getContents() throws CoreException {
+ return editable.getContents();
+ }
+
+ @Override
+ public String getCharset() throws CoreException {
+ return editable.getCharset();
+ }
+ };
+ }
+ return storage;
+ }
+ }
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/LocationEditableRevision.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/LocationEditableRevision.java
index 3c7dc2845..3018b0080 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/LocationEditableRevision.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/LocationEditableRevision.java
@@ -28,6 +28,7 @@ import org.eclipse.egit.ui.Activator;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.team.core.history.IFileRevision;
+import org.eclipse.ui.IEditorInput;
/**
* Editable revision backed by a file outside of the workspace (just IPath).
@@ -88,6 +89,18 @@ public class LocationEditableRevision extends EditableRevision {
}
@Override
+ protected <T> T adaptEditorInput(IEditorInput editorInput,
+ Class<T> adapter) {
+ // Ugly hack to ensure the framework finds the correct document
+ // provider.
+ if (adapter == IFile.class) {
+ return adapter.cast(
+ ResourcesPlugin.getWorkspace().getRoot().getFile(location));
+ }
+ return super.adaptEditorInput(editorInput, adapter);
+ }
+
+ @Override
public int hashCode() {
return 31 * super.hashCode() + Objects.hash(location, runnableContext);
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/ResourceEditableRevision.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/ResourceEditableRevision.java
index b2be7fb49..4c332877e 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/ResourceEditableRevision.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/revision/ResourceEditableRevision.java
@@ -25,6 +25,7 @@ import org.eclipse.egit.ui.Activator;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.team.core.history.IFileRevision;
+import org.eclipse.ui.IEditorInput;
/**
* Editable revision backed by an {@link IFile}. Used for conflict resolutions
@@ -96,6 +97,15 @@ public class ResourceEditableRevision extends EditableRevision
}
@Override
+ protected <T> T adaptEditorInput(IEditorInput editorInput,
+ Class<T> adapter) {
+ if (adapter == IResource.class || adapter == IFile.class) {
+ return adapter.cast(file);
+ }
+ return super.adaptEditorInput(editorInput, adapter);
+ }
+
+ @Override
public int hashCode() {
return 31 * super.hashCode() + Objects.hash(file, runnableContext);
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/compare/LocalNonWorkspaceTypedElement.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/compare/LocalNonWorkspaceTypedElement.java
index 756641917..a5352019d 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/compare/LocalNonWorkspaceTypedElement.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/compare/LocalNonWorkspaceTypedElement.java
@@ -496,6 +496,8 @@ public class LocalNonWorkspaceTypedElement extends LocalResourceTypedElement {
// 544315: the file extension is used to find the document provider only
// if the editor input adapts to IFile.
+ // TODO: Remove when EGit's base platform is Eclipse 4.11 (2019-03)
+
private IResource resource;
public FakeResourceFileStoreEditorInput(IFileStore store, IResource resource) {

Back to the top