Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Dirix2015-05-20 16:04:57 +0000
committerThomas Wolf2016-12-18 09:51:10 +0000
commite3bed9a8e1b86430e6be93ca1029301e64fe1dfa (patch)
tree0f980a72e11983f4125a40fbb03f5a6506597e02
parentab481b10062ee0184adbc65441593d75472f73ec (diff)
downloadegit-e3bed9a8e1b86430e6be93ca1029301e64fe1dfa.tar.gz
egit-e3bed9a8e1b86430e6be93ca1029301e64fe1dfa.tar.xz
egit-e3bed9a8e1b86430e6be93ca1029301e64fe1dfa.zip
Compare/ReplaceWithPrevious support for multiple resources (in mappings)
The CompareWithPrevious and ReplaceWithPrevious actions now also support scenarios where the current selection consists of a single object but maps to multiple files (commonly via ResourceMappings). The previous commit is the next-to-last commit which touched any of the resources. Bug: 496916 Change-Id: I1a208bd9949711e602309cac702a5a158b0eab4b Signed-off-by: Stefan Dirix <sdirix@eclipsesource.com> Signed-off-by: Philip Langer <planger@eclipsesource.com> Also-by: Laurent Delaigue <laurent.delaigue@obeo.fr> Also-by: Mathieu Cartaud <mathieu.cartaud@obeo.fr>
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java23
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithPreviousActionHandler.java75
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ReplaceWithPreviousActionHandler.java32
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryActionHandler.java73
4 files changed, 143 insertions, 60 deletions
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java
index bc738fce5e..0078fd799e 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CommonUtils.java
@@ -6,6 +6,7 @@
* Copyright (C) 2014, IBM Corporation (Markus Keller <markus_keller@ch.ibm.com>)
* Copyright (C) 2015, IBM Corporation (Dani Megert <daniel_megert@ch.ibm.com>)
* Copyright (C) 2015, Thomas Wolf <thomas.wolf@paranor.ch>
+ * Copyright (C) 2016, Stefan Dirix <sdirix@eclipsesource.com>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -18,6 +19,7 @@ import java.nio.file.Path;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
+import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -29,6 +31,7 @@ import org.eclipse.core.resources.IResource;
import org.eclipse.jface.util.Policy;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.util.StringUtils;
import org.eclipse.ui.ISources;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
@@ -263,4 +266,24 @@ public class CommonUtils {
}
return -1;
}
+
+ /**
+ * Creates a comma separated list of all non-null resource names. The last
+ * element is separated with an ampersand.
+ *
+ * @param resources
+ * the collection of {@link IResource}s.
+ * @return A comma separated list the resource names. The last element is
+ * separated with an ampersand.
+ */
+ public static String getResourceNames(Iterable<IResource> resources) {
+ final List<String> names = new LinkedList<>();
+ for (IResource resource : resources) {
+ if (resource.getName() != null) {
+ names.add(resource.getName());
+ }
+ }
+
+ return StringUtils.join(names, ", ", " & "); //$NON-NLS-1$ //$NON-NLS-2$
+ }
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithPreviousActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithPreviousActionHandler.java
index 56f0033f4b..78c744382a 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithPreviousActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithPreviousActionHandler.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2013 GitHub Inc. and others.
+ * Copyright (c) 2011, 2016 GitHub Inc. and others.
* 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
@@ -9,12 +9,14 @@
* Kevin Sawicki (GitHub Inc.) - initial API and implementation
* François Rey - gracefully ignore linked resources
* Laurent Goubet <laurent.goubet@obeo.fr>
+ * Stefan Dirix <sdirix@eclipsesource.com>
*******************************************************************************/
package org.eclipse.egit.ui.internal.actions;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
@@ -22,10 +24,12 @@ import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IResource;
import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.CommonUtils;
import org.eclipse.egit.ui.internal.CompareUtils;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.dialogs.CommitSelectDialog;
import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
@@ -48,23 +52,24 @@ public class CompareWithPreviousActionHandler extends RepositoryActionHandler {
if (repository == null) {
return null;
}
-
final IResource[] resources = getSelectedResources(event);
- if (resources.length != 1) {
- return null;
- }
- try {
- IWorkbenchPage workBenchPage = HandlerUtil
- .getActiveWorkbenchWindowChecked(event).getActivePage();
- final PreviousCommit previous = getPreviousRevision(event,
- resources[0]);
- if (previous != null) {
- CompareUtils.compare(resources, repository, Constants.HEAD,
- previous.commit.getName(), true, workBenchPage);
+ if (resources != null && resources.length > 0) {
+ try {
+ IWorkbenchPage workBenchPage = HandlerUtil
+ .getActiveWorkbenchWindowChecked(event).getActivePage();
+ final RevCommit previous = getPreviousRevision(event,
+ resources);
+ if (previous != null) {
+ CompareUtils.compare(resources, repository, Constants.HEAD,
+ previous.getName(), true, workBenchPage);
+ } else {
+ showNotFoundDialog(event, resources);
+ }
+ } catch (Exception e) {
+ Activator.handleError(
+ UIText.CompareWithRefAction_errorOnSynchronize, e,
+ true);
}
- } catch (Exception e) {
- Activator.handleError(
- UIText.CompareWithRefAction_errorOnSynchronize, e, true);
}
return null;
@@ -72,25 +77,26 @@ public class CompareWithPreviousActionHandler extends RepositoryActionHandler {
@Override
public boolean isEnabled() {
- IResource[] selectedResources = getSelectedResources();
- return super.isEnabled() && selectedResources.length == 1 &&
- selectionMapsToSingleRepository();
+ IStructuredSelection selection = getSelection();
+ return super.isEnabled() && selection.size() == 1
+ && selectionMapsToSingleRepository();
}
- private PreviousCommit getPreviousRevision(final ExecutionEvent event,
- final IResource resource) throws IOException {
+ private RevCommit getPreviousRevision(final ExecutionEvent event,
+ final IResource[] resources) throws IOException {
+ final List<RevCommit> previousList = findPreviousCommits(
+ Arrays.asList(resources));
- final List<PreviousCommit> previousList = findPreviousCommits();
+ final AtomicReference<RevCommit> previous = new AtomicReference<>();
- final AtomicReference<PreviousCommit> previous = new AtomicReference<>();
- if (previousList.size() == 0)
- showNotFoundDialog(event, resource);
- else if (previousList.size() == 1)
+ if (previousList.size() == 0) {
+ return null;
+ } else if (previousList.size() == 1)
previous.set(previousList.get(0));
else {
final List<RevCommit> commits = new ArrayList<>();
- for (PreviousCommit pc : previousList)
- commits.add(pc.commit);
+ for (RevCommit pc : previousList)
+ commits.add(pc);
HandlerUtil.getActiveShell(event).getDisplay()
.syncExec(new Runnable() {
@Override
@@ -98,9 +104,8 @@ public class CompareWithPreviousActionHandler extends RepositoryActionHandler {
CommitSelectDialog dlg = new CommitSelectDialog(
HandlerUtil.getActiveShell(event), commits);
if (dlg.open() == Window.OK)
- for (PreviousCommit pc : previousList)
- if (pc.commit.equals(dlg
- .getSelectedCommit())) {
+ for (RevCommit pc : previousList)
+ if (pc.equals(dlg.getSelectedCommit())) {
previous.set(pc);
break;
}
@@ -112,10 +117,14 @@ public class CompareWithPreviousActionHandler extends RepositoryActionHandler {
}
private void showNotFoundDialog(final ExecutionEvent event,
- IResource resource) {
+ IResource[] resources) {
+
+ final String resourceNames = CommonUtils
+ .getResourceNames(Arrays.asList(resources));
+
final String message = MessageFormat
.format(UIText.CompareWithPreviousActionHandler_MessageRevisionNotFound,
- resource.getName());
+ resourceNames);
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
@Override
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ReplaceWithPreviousActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ReplaceWithPreviousActionHandler.java
index d4585b6fa2..54eb63a098 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ReplaceWithPreviousActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ReplaceWithPreviousActionHandler.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (C) 2012, Mathias Kinzler <mathias.kinzler@sap.com>
+ * Copyright (C) 2012, 2016 Mathias Kinzler <mathias.kinzler@sap.com>
* and other copyright owners as documented in the project's IP log.
*
* All rights reserved. This program and the accompanying materials
@@ -11,16 +11,18 @@ package org.eclipse.egit.ui.internal.actions;
import java.io.IOException;
import java.text.MessageFormat;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.egit.ui.internal.CommonUtils;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.dialogs.CommitSelectDialog;
import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.jgit.revwalk.RevCommit;
@@ -34,33 +36,31 @@ public class ReplaceWithPreviousActionHandler extends
protected String gatherRevision(ExecutionEvent event)
throws ExecutionException {
IResource[] resources = getSelectedResources(event);
- if (resources.length != 1)
- throw new ExecutionException(
- "Unexpected number of selected Resources"); //$NON-NLS-1$
try {
- List<PreviousCommit> pcs = findPreviousCommits();
- List<RevCommit> previousCommits = new ArrayList<>();
- for (PreviousCommit pc: pcs)
- previousCommits.add(pc.commit);
- int parentCount = previousCommits.size();
+ List<RevCommit> pcs = findPreviousCommits(Arrays.asList(resources));
+
+ int parentCount = pcs.size();
if (parentCount == 0) {
+ final String resourceNames = CommonUtils
+ .getResourceNames(Arrays.asList(resources));
+
MessageDialog
.openError(
getShell(event),
UIText.ReplaceWithPreviousActionHandler_NoParentCommitDialogTitle,
MessageFormat
.format(UIText.ReplaceWithPreviousActionHandler_NoParentCommitDialogMessage,
- resources[0].getName()));
+ resourceNames));
throw new OperationCanceledException();
} else if (parentCount > 1) {
CommitSelectDialog dlg = new CommitSelectDialog(
- getShell(event), previousCommits);
+ getShell(event), pcs);
if (dlg.open() == Window.OK)
return dlg.getSelectedCommit().getName();
else
throw new OperationCanceledException();
} else
- return previousCommits.get(0).getName();
+ return pcs.get(0).getName();
} catch (IOException e) {
throw new ExecutionException(e.getMessage(), e);
}
@@ -68,8 +68,8 @@ public class ReplaceWithPreviousActionHandler extends
@Override
public boolean isEnabled() {
- IResource[] selectedResources = getSelectedResources();
- return super.isEnabled() && selectedResources.length == 1 &&
- selectionMapsToSingleRepository();
+ IStructuredSelection selection = getSelection();
+ return super.isEnabled() && selection.size() == 1
+ && selectionMapsToSingleRepository();
}
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryActionHandler.java
index 8b26f23980..cf026ec08b 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryActionHandler.java
@@ -8,6 +8,7 @@
* Copyright (C) 2012, 2013 François Rey <eclipse.org_@_francois_._rey_._name>
* Copyright (C) 2013 Laurent Goubet <laurent.goubet@obeo.fr>
* Copyright (C) 2015, IBM Corporation (Dani Megert <daniel_megert@ch.ibm.com>)
+ * Copyright (C) 2016, Stefan Dirix <sdirix@eclipsesource.com>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -19,6 +20,7 @@ package org.eclipse.egit.ui.internal.actions;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
@@ -51,6 +53,8 @@ import org.eclipse.jgit.revwalk.FollowFilter;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevSort;
import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.filter.OrTreeFilter;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
@@ -454,20 +458,18 @@ abstract class RepositoryActionHandler extends AbstractHandler {
return path;
}
- protected List<PreviousCommit> findPreviousCommits() throws IOException {
- List<PreviousCommit> result = new ArrayList<>();
+ protected RevCommit getHeadCommit(IResource resource) throws IOException {
Repository repository = getRepository();
- IResource resource = getSelectedResources()[0];
if (resource == null) {
- return result;
+ return null;
}
RepositoryMapping mapping = RepositoryMapping.getMapping(resource);
if (mapping == null) {
- return result;
+ return null;
}
String path = mapping.getRepoRelativePath(resource);
if (path == null) {
- return result;
+ return null;
}
try (RevWalk rw = new RevWalk(repository)) {
rw.sort(RevSort.COMMIT_TIME_DESC, true);
@@ -479,7 +481,59 @@ abstract class RepositoryActionHandler extends AbstractHandler {
rw.setTreeFilter(filter);
}
- Ref head = repository.exactRef(Constants.HEAD);
+ Ref head = repository.findRef(Constants.HEAD);
+ if (head == null) {
+ return null;
+ }
+ RevCommit headCommit = rw.parseCommit(head.getObjectId());
+ rw.close();
+ return headCommit;
+ }
+ }
+
+ /**
+ * Returns the previous commit of the given resources.
+ *
+ * @param resources
+ * The {@link IResource} for which the previous commit shall be
+ * determined.
+ * @return The second to last commit which touched any of the given
+ * resources.
+ * @throws IOException
+ * When the commit can not be parsed.
+ */
+ protected List<RevCommit> findPreviousCommits(
+ Collection<IResource> resources) throws IOException {
+ List<RevCommit> result = new ArrayList<>();
+ Repository repository = getRepository();
+ RepositoryMapping mapping = RepositoryMapping.getMapping(resources
+ .iterator().next()
+ .getProject());
+ if (mapping == null) {
+ return result;
+ }
+ try (RevWalk rw = new RevWalk(repository)) {
+ rw.sort(RevSort.COMMIT_TIME_DESC, true);
+ rw.sort(RevSort.BOUNDARY, true);
+
+ List<TreeFilter> filters = new ArrayList<>();
+ DiffConfig diffConfig = repository.getConfig().get(DiffConfig.KEY);
+ for (IResource resource : resources) {
+ String path = mapping.getRepoRelativePath(resource);
+
+ if (path != null && path.length() > 0) {
+ filters.add(FollowFilter.create(path, diffConfig));
+ }
+ }
+
+ if (filters.size() >= 2) {
+ TreeFilter filter = OrTreeFilter.create(filters);
+ rw.setTreeFilter(filter);
+ } else if (filters.size() == 1) {
+ rw.setTreeFilter(filters.get(0));
+ }
+
+ Ref head = repository.findRef(Constants.HEAD);
if (head == null) {
return result;
}
@@ -495,10 +549,7 @@ abstract class RepositoryActionHandler extends AbstractHandler {
RevCommit previousCommit = rw.next();
while (previousCommit != null && result.size() < directParents.size()) {
if (directParents.contains(previousCommit)) {
- String previousPath = getPreviousPath(repository,
- rw.getObjectReader(), headCommit, previousCommit,
- path);
- result.add(new PreviousCommit(previousCommit, previousPath));
+ result.add(previousCommit);
}
previousCommit = rw.next();
}

Back to the top