summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorLaurent Goubet2012-11-14 04:03:38 (EST)
committer Robin Stocker2013-01-18 13:29:19 (EST)
commite7536536b48b48390db875502723c27daf89967a (patch)
treedd8db350a48fcdf732cdc87a8711065e9a9fd64d
parent821cb62ffba577cfd3286e44ac514146298629a0 (diff)
downloadegit-e7536536b48b48390db875502723c27daf89967a.zip
egit-e7536536b48b48390db875502723c27daf89967a.tar.gz
egit-e7536536b48b48390db875502723c27daf89967a.tar.bz2
Improve support for logical models in Compare With operationrefs/changes/59/8559/11
When comparing a file with another branch, tag or reference, take the model providers into account and launch the synchronize perspective instead of comparing the single, selected file into a compare editor if this file is part of a model spanning more than one resource. Bug: 393225 Change-Id: Id113b941afa44109b899c17957baa053bd75158f Also-by: Gunnar Wagenknecht <gunnar@wagenknecht.org> Signed-off-by: Gunnar Wagenknecht <gunnar@wagenknecht.org> Signed-off-by: Robin Stocker <robin@nibor.org>
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ResourceUtil.java45
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java5
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CompareUtils.java50
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithRefActionHandler.java79
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronize.java27
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties3
6 files changed, 181 insertions, 28 deletions
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ResourceUtil.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ResourceUtil.java
index 925d880..b710218 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ResourceUtil.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ResourceUtil.java
@@ -1,6 +1,8 @@
/*******************************************************************************
* Copyright (C) 2011, Jens Baumgart <jens.baumgart@sap.com>
* Copyright (C) 2012, Robin Stocker <robin@nibor.org>
+ * Copyright (C) 2012, Laurent Goubet <laurent.goubet@obeo.fr>
+ * Copyright (C) 2012, Gunnar Wagenknecht <gunnar@wagenknecht.org>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -12,15 +14,23 @@ package org.eclipse.egit.core.internal.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.LinkedHashSet;
import java.util.Map;
+import java.util.Set;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.mapping.IModelProviderDescriptor;
+import org.eclipse.core.resources.mapping.ModelProvider;
+import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.core.resources.mapping.ResourceMappingContext;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.jgit.lib.Repository;
@@ -150,4 +160,39 @@ public class ResourceUtil {
resourcesList.add(path);
}
}
+
+ /**
+ * This will query all model providers for those that are enabled on the
+ * given file and list all mappings available for that file.
+ *
+ * @param file
+ * The file for which we need the associated resource mappings.
+ * @param context
+ * Context from which remote content could be retrieved.
+ * @return All mappings available for that file.
+ */
+ public static ResourceMapping[] getResourceMappings(IFile file,
+ ResourceMappingContext context) {
+ final IModelProviderDescriptor[] modelDescriptors = ModelProvider
+ .getModelProviderDescriptors();
+
+ final Set<ResourceMapping> mappings = new LinkedHashSet<ResourceMapping>();
+ for (IModelProviderDescriptor candidate : modelDescriptors) {
+ try {
+ final IResource[] resources = candidate
+ .getMatchingResources(new IResource[] { file, });
+ if (resources.length > 0) {
+ // get mappings from model provider if there are matching resources
+ final ModelProvider model = candidate.getModelProvider();
+ final ResourceMapping[] modelMappings = model.getMappings(
+ file, context, null);
+ for (ResourceMapping mapping : modelMappings)
+ mappings.add(mapping);
+ }
+ } catch (CoreException e) {
+ Activator.logError(e.getMessage(), e);
+ }
+ }
+ return mappings.toArray(new ResourceMapping[mappings.size()]);
+ }
}
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 0aa6bc4..0d502b6 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
@@ -6,6 +6,8 @@
* Copyright (C) 2012, Mathias Kinzler <mathias.kinzler@sap.com>
* Copyright (C) 2012, Daniel Megert <daniel_megert@ch.ibm.com>
* Copyright (C) 2012, Robin Stocker <robin@nibor.org>
+ * Copyright (C) 2012, Laurent Goubet <laurent.goubet@obeo.fr>
+ * Copyright (C) 2012, Gunnar Wagenknecht <gunnar@wagenknecht.org>
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -2158,6 +2160,9 @@ public class UIText extends NLS {
public static String CompareWithIndexAction_errorOnAddToIndex;
/** */
+ public static String CompareWithRefAction_errorOnSynchronize;
+
+ /** */
public static String CompareWithPreviousActionHandler_MessageRevisionNotFound;
/** */
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CompareUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CompareUtils.java
index 01b2519..aadacf1 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CompareUtils.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CompareUtils.java
@@ -11,6 +11,8 @@
* Stefan Lay (SAP AG) - initial implementation
* Yann Simon <yann.simon.fr@gmail.com> - implementation of getHeadTypedElement
* Robin Stocker <robin@nibor.org>
+ * Laurent Goubet <laurent.goubet@obeo.fr>
+ * Gunnar Wagenknecht <gunnar@wagenknecht.org>
*******************************************************************************/
package org.eclipse.egit.ui.internal;
@@ -28,7 +30,11 @@ import org.eclipse.compare.structuremergeviewer.DiffNode;
import org.eclipse.compare.structuremergeviewer.Differencer;
import org.eclipse.compare.structuremergeviewer.IStructureComparator;
import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.core.resources.mapping.ResourceMappingContext;
+import org.eclipse.core.resources.mapping.ResourceTraversal;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Platform;
@@ -42,6 +48,7 @@ import org.eclipse.egit.core.internal.CompareCoreUtils;
import org.eclipse.egit.core.internal.storage.GitFileRevision;
import org.eclipse.egit.core.internal.storage.WorkingTreeFileRevision;
import org.eclipse.egit.core.internal.storage.WorkspaceFileRevision;
+import org.eclipse.egit.core.internal.util.ResourceUtil;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIText;
@@ -687,4 +694,47 @@ public class CompareUtils {
}
}
+ /**
+ * Indicates if it is OK to open the selected file directly in a compare
+ * editor.
+ * <p>
+ * It is not OK to show the single file if the file is part of a
+ * logical model element that spans multiple files.
+ * </p>
+ *
+ * @param file
+ * file the user is trying to compare
+ * @return <code>true</code> if the file can be opened directly in a compare
+ * editor, <code>false</code> if the synchronize view should be
+ * opened instead.
+ */
+ public static boolean canDirectlyOpenInCompare(IFile file) {
+ /*
+ * Note : it would be better to use a remote context here in order to
+ * give the model provider a chance to resolve the remote logical model
+ * instead of only relying on the local one. However, this might be a
+ * long operation and would not really provide more context : we're
+ * trying to determine if the local file can be compared alone, this can
+ * be done by relying on the local model only.
+ */
+ final ResourceMapping[] mappings = ResourceUtil.getResourceMappings(
+ file, ResourceMappingContext.LOCAL_CONTEXT);
+
+ for (ResourceMapping mapping : mappings) {
+ try {
+ final ResourceTraversal[] traversals = mapping.getTraversals(
+ ResourceMappingContext.LOCAL_CONTEXT, null);
+ for (ResourceTraversal traversal : traversals) {
+ final IResource[] resources = traversal.getResources();
+ for (IResource resource : resources) {
+ if (!resource.equals(file))
+ return false;
+ }
+ }
+ } catch (CoreException e) {
+ Activator.logError(e.getMessage(), e);
+ }
+ }
+ return true;
+ }
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithRefActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithRefActionHandler.java
index d0d330b..34f5e6e 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithRefActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithRefActionHandler.java
@@ -5,6 +5,11 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Mathias Kinzler <mathias.kinzler@sap.com>
+ * Laurent Goubet <laurent.goubet@obeo.fr>
+ * Gunnar Wagenknecht <gunnar@wagenknecht.org>
*******************************************************************************/
package org.eclipse.egit.ui.internal.actions;
@@ -17,13 +22,19 @@ 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.mapping.ResourceMapping;
+import org.eclipse.core.resources.mapping.ResourceMappingContext;
+import org.eclipse.egit.core.internal.util.ResourceUtil;
import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIText;
import org.eclipse.egit.ui.internal.CompareUtils;
import org.eclipse.egit.ui.internal.GitCompareFileRevisionEditorInput;
import org.eclipse.egit.ui.internal.dialogs.CompareTargetSelectionDialog;
import org.eclipse.egit.ui.internal.dialogs.CompareTreeView;
+import org.eclipse.egit.ui.internal.synchronize.GitModelSynchronize;
import org.eclipse.jface.window.Window;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
@@ -54,29 +65,11 @@ public class CompareWithRefActionHandler extends RepositoryActionHandler {
if (resources.length == 1 && resources[0] instanceof IFile) {
final IFile baseFile = (IFile) resources[0];
- final ITypedElement base = SaveableCompareEditorInput
- .createFileElement(baseFile);
-
- final ITypedElement next;
- ITypedElement ancestor = null;
- try {
- RepositoryMapping mapping = RepositoryMapping
- .getMapping(resources[0]);
- next = getElementForRef(mapping.getRepository(), mapping
- .getRepoRelativePath(baseFile), dlg.getRefName());
- ancestor = CompareUtils.getFileRevisionTypedElementForCommonAncestor(
- mapping.getRepoRelativePath(baseFile), repo.resolve(Constants.HEAD),
- repo.resolve(dlg.getRefName()), repo);
- } catch (IOException e) {
- Activator.handleError(
- UIText.CompareWithIndexAction_errorOnAddToIndex, e,
- true);
- return null;
+ if (CompareUtils.canDirectlyOpenInCompare(baseFile)) {
+ showSingleFileComparison(baseFile, dlg.getRefName());
+ } else {
+ synchronizeModel(baseFile, repo, dlg.getRefName());
}
- final GitCompareFileRevisionEditorInput in = new GitCompareFileRevisionEditorInput(
- base, next, ancestor, null);
- in.getCompareConfiguration().setRightLabel(dlg.getRefName());
- CompareUI.openCompareEditor(in);
} else {
CompareTreeView view;
try {
@@ -92,6 +85,48 @@ public class CompareWithRefActionHandler extends RepositoryActionHandler {
return null;
}
+ private void showSingleFileComparison(IFile file, String refName) {
+ final ITypedElement base = SaveableCompareEditorInput
+ .createFileElement(file);
+
+ final ITypedElement next;
+ try {
+ RepositoryMapping mapping = RepositoryMapping.getMapping(file);
+ next = getElementForRef(mapping.getRepository(),
+ mapping.getRepoRelativePath(file), refName);
+ } catch (IOException e) {
+ Activator.handleError(
+ UIText.CompareWithIndexAction_errorOnAddToIndex, e, true);
+ return;
+ }
+
+ final GitCompareFileRevisionEditorInput in = new GitCompareFileRevisionEditorInput(
+ base, next, null);
+ in.getCompareConfiguration().setRightLabel(refName);
+ CompareUI.openCompareEditor(in);
+ }
+
+ private void synchronizeModel(final IFile file, Repository repo,
+ String refName) {
+ try {
+ final GitSynchronizeData data = new GitSynchronizeData(repo,
+ Constants.HEAD, refName, true);
+ final GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(
+ data);
+
+ // use all available local mappings for proper model support
+ final ResourceMapping[] mappings = ResourceUtil
+ .getResourceMappings(file,
+ ResourceMappingContext.LOCAL_CONTEXT);
+
+ GitModelSynchronize.launch(dataSet, mappings);
+ } catch (IOException e) {
+ Activator.handleError(
+ UIText.CompareWithRefAction_errorOnSynchronize, e, true);
+ return;
+ }
+ }
+
private ITypedElement getElementForRef(final Repository repository,
final String gitPath, final String refName) throws IOException {
ObjectId commitId = repository.resolve(refName + "^{commit}"); //$NON-NLS-1$
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronize.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronize.java
index 753c5c6..b2250e7 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronize.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronize.java
@@ -1,5 +1,7 @@
/*******************************************************************************
* Copyright (C) 2010, 2012 Dariusz Luksza <dariusz@luksza.org>.
+ * Copyright (C) 2012, Laurent Goubet <laurent.goubet@obeo.fr>
+ * Copyright (C) 2012, Gunnar Wagenknecht <gunnar@wagenknecht.org>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -42,7 +44,7 @@ import org.eclipse.ui.PlatformUI;
*/
public class GitModelSynchronize {
- private static final String providerId = "org.eclipse.egit.core.GitProvider"; //$NON-NLS-1$
+ private static final String GIT_PROVIDER_ID = "org.eclipse.egit.core.GitProvider"; //$NON-NLS-1$
/**
* Launches Git Model synchronization action
@@ -63,7 +65,20 @@ public class GitModelSynchronize {
*/
public static final void launch(final GitSynchronizeDataSet gsdSet,
IResource[] resources) {
- ResourceMapping[] mappings = getSelectedResourceMappings(resources);
+ ResourceMapping[] mappings = getGitResourceMappings(resources);
+
+ launch(gsdSet, mappings);
+ }
+
+ /**
+ * Launches Git Model synchronization action using the specified resource
+ * mapping
+ *
+ * @param gsdSet
+ * @param mappings
+ */
+ public static final void launch(final GitSynchronizeDataSet gsdSet,
+ ResourceMapping[] mappings) {
IWorkbenchWindow window = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow();
@@ -78,7 +93,7 @@ public class GitModelSynchronize {
* @return the resource mappings that contain resources associated with the
* given provider
*/
- private static ResourceMapping[] getSelectedResourceMappings(
+ private static ResourceMapping[] getGitResourceMappings(
IResource[] elements) {
List<ResourceMapping> providerMappings = new ArrayList<ResourceMapping>();
@@ -87,7 +102,7 @@ public class GitModelSynchronize {
if (adapted != null && adapted instanceof ResourceMapping) {
ResourceMapping mapping = (ResourceMapping) adapted;
- if (isMappedToProvider(mapping))
+ if (isMappedToGitProvider(mapping))
providerMappings.add(mapping);
}
}
@@ -119,13 +134,13 @@ public class GitModelSynchronize {
* @return <code>true</code> if resource is mapped to Git provider,
* <code>false</code> otherwise
*/
- private static boolean isMappedToProvider(ResourceMapping element) {
+ private static boolean isMappedToGitProvider(ResourceMapping element) {
IProject[] projects = element.getProjects();
for (IProject project: projects) {
RepositoryProvider provider = RepositoryProvider
.getProvider(project);
- if (provider != null && provider.getID().equals(providerId))
+ if (provider != null && provider.getID().equals(GIT_PROVIDER_ID))
return true;
}
return false;
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 8140f08..6fbae53 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
@@ -12,6 +12,7 @@
# - Added context menu to the Commit Editor's header text
# Markus Keller <markus_keller@ch.ibm.com> - Show the repository name in the title of the Pull Result dialog
# Daniel Megert <daniel_megert@ch.ibm.com> - Use correct syntax when a single ref was updated
+# Gunnar Wagenknecht <gunnar@wagenknecht.org>
###############################################################################
AbortRebaseCommand_CancelDialogMessage=The abort operation was canceled
AbortRebaseCommand_JobName=Aborting Rebase
@@ -718,6 +719,8 @@ CompareWithIndexAction_errorOnAddToIndex=Error during adding to index
CompareWithPreviousActionHandler_MessageRevisionNotFound=No previous revision of {0} could be found in the repository.
CompareWithPreviousActionHandler_TaskGeneratingInput=Generating comparison with previous revision
CompareWithPreviousActionHandler_TitleRevisionNotFound=Previous revision not found
+CompareWithRefAction_errorOnSynchronize=Error reading from repository while preparing input for compare operation.
+
CompareUtils_errorCommonAncestor=Error finding common ancestor for {0} and {1}
ConfirmationPage_cantConnectToAnyTitle=Can't Connect