From a8f3b251792dc203433db89300c744c55c8ab4b0 Mon Sep 17 00:00:00 2001 From: Thomas Wolf Date: Mon, 2 Jul 2018 13:06:22 +0200 Subject: [PATCH] Do not refresh projects that use a PessimisticResourceRuleFactory With some setups where the Eclipse workspace is inside the git working tree EGit may end up trying to refresh a project that needs the workspace root as scheduling rule for a refresh. EGit generally uses multi-rules containing affected projects, though, and thus it may run into an IAE in that case. EGit-managed projects use an optimistic rule factory that uses the project itself as scheduling rule. So do normal unshared projects. So this can only occur if there are projects inside the git working tree that are not shared with EGit but with some other provider that does not use an optimistic rule factory. This is a rare occurrence, and such projects had better be git-ignored, too. Not refreshing such projects is a thus viable approach. Bug: 536472 Change-Id: I17c06fd69e232a7b864a98c4e95598fa7ab6b7b0 Signed-off-by: Thomas Wolf --- .../egit/core/internal/util/ProjectUtilTest.java | 22 ++++++++++------------ .../egit/core/internal/util/ProjectUtil.java | 6 +++++- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/util/ProjectUtilTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/util/ProjectUtilTest.java index 55f72dea3..3c221e0af 100644 --- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/util/ProjectUtilTest.java +++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/util/ProjectUtilTest.java @@ -19,8 +19,8 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import java.io.ByteArrayInputStream; import java.io.File; @@ -98,7 +98,7 @@ public class ProjectUtilTest extends GitTestCase { IProject[] projectSelf = ProjectUtil.getProjectsContaining( repository.getRepository(), Collections.singleton("Project-1")); - Set files = new TreeSet(); + Set files = new TreeSet<>(); files.add("Project-1/xxx"); files.add("Project-1/zzz"); IProject[] multiFile = ProjectUtil.getProjectsContaining( @@ -147,7 +147,7 @@ public class ProjectUtilTest extends GitTestCase { IProject[] projectSelf = ProjectUtil.getProjectsContaining( repository.getRepository(), Collections.singleton("Project-1")); - Set files = new TreeSet(); + Set files = new TreeSet<>(); files.add("Project-1/xxx"); files.add("Project-1/zzz"); IProject[] multiFile = ProjectUtil.getProjectsContaining( @@ -197,10 +197,8 @@ public class ProjectUtilTest extends GitTestCase { @Test public void testRefreshValidProjects() throws Exception { - IProject p = mock(IProject.class); - when(p.getLocation()).thenReturn(project.getProject().getLocation()); - IProject[] projects = new IProject[1]; - projects[0] = p; + IProject p = spy(project.getProject()); + IProject[] projects = { p }; ProjectUtil.refreshValidProjects(projects, new NullProgressMonitor()); verify(p).refreshLocal(eq(IResource.DEPTH_INFINITE), any(IProgressMonitor.class)); @@ -248,21 +246,21 @@ public class ProjectUtilTest extends GitTestCase { @Test public void testFindProjectFiles() { - Collection files = new ArrayList(); + Collection files = new ArrayList<>(); assertTrue(ProjectUtil.findProjectFiles(files, gitDir.getParentFile(), true, new NullProgressMonitor())); } @Test public void testFindProjectFilesNullDir() { - Collection files = new ArrayList(); + Collection files = new ArrayList<>(); assertFalse(ProjectUtil.findProjectFiles(files, null, true, new NullProgressMonitor())); } @Test public void testFindProjectFilesEmptyDir() throws Exception { - Collection files = new ArrayList(); + Collection files = new ArrayList<>(); File dir = new File(gitDir.getParentFile().getPath() + File.separator + "xxx"); FileUtils.mkdir(dir); @@ -275,7 +273,7 @@ public class ProjectUtilTest extends GitTestCase { project2 = new TestProject(true, "Project-1/Project-Nested"); File workingDir = gitDir.getParentFile(); - Collection nestedResult = new ArrayList(); + Collection nestedResult = new ArrayList<>(); boolean nestedFound = ProjectUtil.findProjectFiles(nestedResult, workingDir, true, new NullProgressMonitor()); @@ -287,7 +285,7 @@ public class ProjectUtilTest extends GitTestCase { assertThat(nestedResult, hasItem(new File(workingDir, "Project-1/Project-Nested/.project"))); - Collection noNestedResult = new ArrayList(); + Collection noNestedResult = new ArrayList<>(); boolean noNestedFound = ProjectUtil.findProjectFiles(noNestedResult, workingDir, false, new NullProgressMonitor()); assertTrue("Expected to find projects", noNestedFound); diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ProjectUtil.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ProjectUtil.java index 11cb2ad8c..ad01f32f9 100644 --- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ProjectUtil.java +++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ProjectUtil.java @@ -31,6 +31,7 @@ import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceRuleFactory; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; @@ -134,11 +135,14 @@ public class ProjectUtil { IProgressMonitor monitor) throws CoreException { SubMonitor progress = SubMonitor.convert(monitor, CoreText.ProjectUtil_refreshingProjects, projects.length); + IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace() + .getRuleFactory(); for (IProject p : projects) { if (progress.isCanceled()) break; IPath projectLocation = p.getLocation(); - if (projectLocation == null) { + if (projectLocation == null + || !p.contains(ruleFactory.refreshRule(p))) { progress.worked(1); continue; } -- 2.11.4.GIT