When we are looking up the mapping for a file contained within a linked directory the linked directory may be mapped to a Git repository that is not the same as the project itself, or the project doesn't even have a Git repository. This may also be necessary for submodules. For example a single project in Eclipse may actually contain several Git submodules below it and each must have its own RepositoryMapping. We now store the RepositoryMapping for a given IContainer directly on that container using a session property. This way Eclipse manages the hash lookups for us, and we can efficiently walk up the tree to locate the nearest mapping for any resource. Signed-off-by: Shawn O. Pearce <spearce@xxxxxxxxxxx> --- .../spearce/egit/core/project/GitProjectData.java | 47 +++++++++++++------- 1 files changed, 31 insertions(+), 16 deletions(-) diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/project/GitProjectData.java b/org.spearce.egit.core/src/org/spearce/egit/core/project/GitProjectData.java index 3d5424c..9998880 100644 --- a/org.spearce.egit.core/src/org/spearce/egit/core/project/GitProjectData.java +++ b/org.spearce.egit.core/src/org/spearce/egit/core/project/GitProjectData.java @@ -32,6 +32,7 @@ import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Preferences; +import org.eclipse.core.runtime.QualifiedName; import org.eclipse.osgi.util.NLS; import org.eclipse.team.core.RepositoryProvider; import org.spearce.egit.core.Activator; @@ -71,6 +72,9 @@ public class GitProjectData { } } + private static QualifiedName MAPPING_KEY = new QualifiedName( + GitProjectData.class.getName(), "RepositoryMapping"); + /** * Start listening for resource changes. * @@ -226,8 +230,6 @@ public class GitProjectData { private final Collection mappings; - private final Map c2mapping; - private final Set protectedResources; /** @@ -239,7 +241,6 @@ public class GitProjectData { public GitProjectData(final IProject p) { project = p; mappings = new ArrayList(); - c2mapping = new HashMap(); protectedResources = new HashSet(); } @@ -267,15 +268,16 @@ public class GitProjectData { * @throws CoreException */ public void markTeamPrivateResources() throws CoreException { - final Iterator i = c2mapping.entrySet().iterator(); - while (i.hasNext()) { - final Map.Entry e = (Map.Entry) i.next(); - final IContainer c = (IContainer) e.getKey(); + for (final Object rmObj : mappings) { + final RepositoryMapping rm = (RepositoryMapping)rmObj; + final IContainer c = rm.getContainer(); + if (c == null) + continue; // Not fully mapped yet? + final IResource dotGit = c.findMember(".git"); if (dotGit != null) { try { - final Repository r = ((RepositoryMapping) e.getValue()) - .getRepository(); + final Repository r = rm.getRepository(); final File dotGitDir = dotGit.getLocation().toFile() .getCanonicalFile(); if (dotGitDir.equals(r.getDirectory())) { @@ -298,14 +300,23 @@ public class GitProjectData { } /** - * TODO: check usage, we should probably declare the parameter - * as IProject. - * - * @param r Eclipse project + * @param r any workbench resource contained within this project. * @return the mapping for the specified project */ - public RepositoryMapping getRepositoryMapping(final IResource r) { - return (RepositoryMapping) c2mapping.get(r); + public RepositoryMapping getRepositoryMapping(IResource r) { + try { + while (r != null) { + final RepositoryMapping m; + + m = (RepositoryMapping) r.getSessionProperty(MAPPING_KEY); + if (m != null) + return m; + r = r.getParent(); + } + } catch (CoreException err) { + Activator.logError("Falied finding RepositoryMapping", err); + } + return null; } private void delete() { @@ -445,7 +456,11 @@ public class GitProjectData { m.fireRepositoryChanged(); trace("map " + c + " -> " + m.getRepository()); - c2mapping.put(c, m); + try { + c.setSessionProperty(MAPPING_KEY, m); + } catch (CoreException err) { + Activator.logError("Failed to cache RepositoryMapping", err); + } dotGit = c.findMember(".git"); if (dotGit != null && dotGit.getLocation().toFile().equals(git)) { -- 1.6.0.rc1.250.g9b5e2 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html