From 96d430a13d0e9210ccf563d42ba94c202d578d18 Mon Sep 17 00:00:00 2001 From: Thomas Wolf Date: Fri, 29 Jun 2018 17:05:33 +0200 Subject: [PATCH] Fix error marker updates in staging view Use (absolute) paths instead of resources to determine which elements to update in the staging viewer. Using resources may give inconsistent results if * a file occurs several times in the Eclipse resource tree, or * a on-disk directory doesn't exist as a resource in Eclipse at all. The latter can occur if tree representation is used and an Eclipse project lives in some sub-directory (for instance, "bundles") in the git working tree. In that case the staging view will have a folder "bundles", but there's no resource for it, and thus our top-down tree traversal will skip it and all its descendants. Bug: 536471 Change-Id: I46fc84737471e2994af056ecb238b3bbfb55e413 Signed-off-by: Thomas Wolf --- .../internal/decorators/ProblemLabelDecorator.java | 60 ++++++++++++++++------ 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/ProblemLabelDecorator.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/ProblemLabelDecorator.java index 23a28570c..e5dd1fa39 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/ProblemLabelDecorator.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/ProblemLabelDecorator.java @@ -11,6 +11,7 @@ *******************************************************************************/ package org.eclipse.egit.ui.internal.decorators; +import java.io.File; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -22,7 +23,10 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; import org.eclipse.egit.core.AdapterUtils; +import org.eclipse.egit.core.project.RepositoryMapping; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.LocalResourceManager; @@ -108,26 +112,42 @@ public class ProblemLabelDecorator extends BaseLabelProvider implements @Override public void resourceChanged(IResourceChangeEvent event) { - Set resources = new HashSet<>(); + Set paths = new HashSet<>(); IMarkerDelta[] markerDeltas = event.findMarkerDeltas(IMarker.PROBLEM, true); for (IMarkerDelta delta : markerDeltas) { - // Also add parents IResource resource = delta.getResource(); - while (resource.getType() != IResource.ROOT - && resources.add(resource)) { - resource = resource.getParent(); + if (resource == null) { + continue; + } + RepositoryMapping mapping = RepositoryMapping.getMapping(resource); + if (mapping == null || mapping.getRepository().isBare()) { + continue; + } + IPath path = resource.getLocation(); + if (path == null) { + continue; + } + // Also add parents + File workTree = mapping.getWorkTree(); + if (workTree == null) { + continue; + } + int n = new Path(workTree.getAbsolutePath()).segmentCount(); + for (int i = path.segmentCount(); i > n; i--) { + paths.add(path); + path = path.removeLastSegments(1); } } - if (!resources.isEmpty()) { - updateLabels(resources); + if (!paths.isEmpty()) { + updateLabels(paths); } } - private void updateLabels(Set changedResources) { - List elements = getAffectedElements(changedResources); + private void updateLabels(Set changedPaths) { + List elements = getAffectedElements(changedPaths); if (!elements.isEmpty()) { final Object[] updateElements = elements.toArray(new Object[elements.size()]); Display display = viewer.getControl().getDisplay(); @@ -141,25 +161,31 @@ public class ProblemLabelDecorator extends BaseLabelProvider implements } } - private List getAffectedElements(Set resources) { + private List getAffectedElements(Set paths) { List result = new ArrayList<>(); if (viewer.getContentProvider() instanceof IStructuredContentProvider) { IStructuredContentProvider contentProvider = (IStructuredContentProvider) viewer.getContentProvider(); - getAffectedElements(resources, contentProvider.getElements(null), + getAffectedElements(paths, contentProvider.getElements(null), contentProvider, result); } return result; } - private void getAffectedElements(Set resources, - Object[] elements, IStructuredContentProvider contentProvider, - List result) { + private void getAffectedElements(Set paths, Object[] elements, + IStructuredContentProvider contentProvider, List result) { for (Object element : elements) { - IResource resource = AdapterUtils.adapt(element, IResource.class); - if (resource != null && resources.contains(resource)) { + IPath path = AdapterUtils.adapt(element, IPath.class); + if (path == null) { + IResource resource = AdapterUtils.adapt(element, + IResource.class); + if (resource != null) { + path = resource.getLocation(); + } + } + if (path != null && paths.contains(path)) { result.add(element); if (contentProvider instanceof ITreeContentProvider) { - getAffectedElements(resources, + getAffectedElements(paths, ((ITreeContentProvider) contentProvider) .getChildren(element), contentProvider, result); -- 2.11.4.GIT