[EGIT PATCH 3/5] Fix RepositoryMapping.getRepoRelativePath to honor linked resources

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If a project resource is linked to a repository working directory we
should be locating the path of the resource within the repository by
the path it appears in the filesystem, not the path it appears at in
the Eclipse project structure.  By using the filesystem location we
can ensure the paths match what C Git would see when accessing the
same resource.

By making this change we can now safely remove the subset concept
from RepositoryMapping as it was a crude form of trying to come up
with the same result when projects appeared within a repository.

Signed-off-by: Shawn O. Pearce <spearce@xxxxxxxxxxx>
---
 .../egit/core/op/ConnectProviderOperation.java     |   14 +----
 .../egit/core/project/RepositoryFinder.java        |   11 +--
 .../egit/core/project/RepositoryMapping.java       |   65 ++++++++-----------
 3 files changed, 32 insertions(+), 58 deletions(-)

diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/op/ConnectProviderOperation.java b/org.spearce.egit.core/src/org/spearce/egit/core/op/ConnectProviderOperation.java
index 3ed3569..bf814f4 100644
--- a/org.spearce.egit.core/src/org/spearce/egit/core/op/ConnectProviderOperation.java
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/op/ConnectProviderOperation.java
@@ -15,10 +15,8 @@ import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.IWorkspaceRunnable;
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.team.core.RepositoryProvider;
 import org.spearce.egit.core.Activator;
@@ -70,17 +68,7 @@ public class ConnectProviderOperation implements IWorkspaceRunnable {
 
 					db = new Repository(newGitDir);
 					db.create();
-					IPath gitDirParent = Path.fromOSString(
-							db.getDirectory().getAbsolutePath())
-							.removeLastSegments(1);
-					IPath cPath = project.getLocation();
-					String subset = null;
-					if (gitDirParent.isPrefixOf(cPath)) {
-						int n = cPath.matchingFirstSegments(gitDirParent);
-						subset = cPath.removeFirstSegments(n).toPortableString();
-					}
-					repos.add(new RepositoryMapping(project, db.getDirectory(),
-							subset));
+					repos.add(new RepositoryMapping(project, db.getDirectory()));
 					db.close();
 
 					// If we don't refresh the project directory right
diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/project/RepositoryFinder.java b/org.spearce.egit.core/src/org/spearce/egit/core/project/RepositoryFinder.java
index 68cf79c..116a7bf 100644
--- a/org.spearce.egit.core/src/org/spearce/egit/core/project/RepositoryFinder.java
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/project/RepositoryFinder.java
@@ -92,17 +92,15 @@ public class RepositoryFinder {
 				final IResource[] children;
 
 				if (ownCfg.isFile()) {
-					register(c, ownCfg.getParentFile(), null);
+					register(c, ownCfg.getParentFile());
 				} else if (c.isLinked() || c instanceof IProject) {
-					String s = fsLoc.getName();
 					File p = fsLoc.getParentFile();
 					while (p != null) {
 						final File pCfg = configFor(p);
 						if (pCfg.isFile()) {
-							register(c, pCfg.getParentFile(), s);
+							register(c, pCfg.getParentFile());
 							break;
 						}
-						s = p.getName() + "/" + s;
 						p = p.getParentFile();
 					}
 				}
@@ -132,14 +130,13 @@ public class RepositoryFinder {
 		return new File(new File(fsLoc, ".git"), "config");
 	}
 
-	private void register(final IContainer c, final File gitdir,
-			final String subset) {
+	private void register(final IContainer c, final File gitdir) {
 		File f;
 		try {
 			f = gitdir.getCanonicalFile();
 		} catch (IOException ioe) {
 			f = gitdir.getAbsoluteFile();
 		}
-		results.add(new RepositoryMapping(c, f, subset));
+		results.add(new RepositoryMapping(c, f));
 	}
 }
diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/project/RepositoryMapping.java b/org.spearce.egit.core/src/org/spearce/egit/core/project/RepositoryMapping.java
index 6a0b56f..17e8142 100644
--- a/org.spearce.egit.core/src/org/spearce/egit/core/project/RepositoryMapping.java
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/project/RepositoryMapping.java
@@ -41,10 +41,10 @@ public class RepositoryMapping {
 
 	private final String gitdirPath;
 
-	private final String subset;
-
 	private Repository db;
 
+	private String workdirPrefix;
+
 	private IContainer container;
 
 	/**
@@ -55,12 +55,9 @@ public class RepositoryMapping {
 	 */
 	public RepositoryMapping(final Properties p, final String initialKey) {
 		final int dot = initialKey.lastIndexOf('.');
-		String s;
 
 		containerPath = initialKey.substring(0, dot);
 		gitdirPath = p.getProperty(initialKey);
-		s = p.getProperty(containerPath + ".subset");
-		subset = "".equals(s) ? null : s;
 	}
 
 	/**
@@ -69,10 +66,8 @@ public class RepositoryMapping {
 	 *
 	 * @param mappedContainer
 	 * @param gitDir
-	 * @param subsetRoot
 	 */
-	public RepositoryMapping(final IContainer mappedContainer,
-			final File gitDir, final String subsetRoot) {
+	public RepositoryMapping(final IContainer mappedContainer, final File gitDir) {
 		final IPath cLoc = mappedContainer.getLocation()
 				.removeTrailingSeparator();
 		final IPath gLoc = Path.fromOSString(gitDir.getAbsolutePath())
@@ -98,8 +93,6 @@ public class RepositoryMapping {
 		} else {
 			gitdirPath = gLoc.toPortableString();
 		}
-
-		subset = "".equals(subsetRoot) ? null : subsetRoot;
 	}
 
 	IPath getContainerPath() {
@@ -111,17 +104,6 @@ public class RepositoryMapping {
 	}
 
 	/**
-	 * Eclipse projects typically reside one or more levels
-	 * below the repository. This method return the relative
-	 * path to the project. Null is returned instead of "".
-	 *
-	 * @return relative path from repository to project, or null
-	 */
-	public String getSubset() {
-		return subset;
-	}
-
-	/**
 	 * @return the workdir file, i.e. where the files are checked out
 	 */
 	public File getWorkDir() {
@@ -130,6 +112,7 @@ public class RepositoryMapping {
 
 	synchronized void clear() {
 		db = null;
+		workdirPrefix = null;
 		container = null;
 	}
 
@@ -142,6 +125,15 @@ public class RepositoryMapping {
 
 	synchronized void setRepository(final Repository r) {
 		db = r;
+
+		try {
+			workdirPrefix = getWorkDir().getCanonicalPath();
+		} catch (IOException err) {
+			workdirPrefix = getWorkDir().getAbsolutePath();
+		}
+		workdirPrefix = workdirPrefix.replace('\\', '/');
+		if (!workdirPrefix.endsWith("/"))
+			workdirPrefix += "/";
 	}
 
 	/**
@@ -166,9 +158,6 @@ public class RepositoryMapping {
 
 	synchronized void store(final Properties p) {
 		p.setProperty(containerPath + ".gitdir", gitdirPath);
-		if (subset != null && !"".equals(subset)) {
-			p.setProperty(containerPath + ".subset", subset);
-		}
 	}
 
 	public String toString() {
@@ -209,20 +198,20 @@ public class RepositoryMapping {
 	 * @param rsrc
 	 * @return the path relative to the Git repository, including base name.
 	 */
-	public String getRepoRelativePath(IResource rsrc) {
-		String prefix = getSubset();
-		String projectRelativePath = rsrc.getProjectRelativePath().toString();
-		String repoRelativePath;
-		if (prefix != null) {
-			if (projectRelativePath.length() == 0)
-				repoRelativePath = prefix;
-			else
-				repoRelativePath = prefix + "/" + projectRelativePath;
-		} else
-			repoRelativePath = projectRelativePath;
-
-		assert repoRelativePath != null;
-		return repoRelativePath;
+	public String getRepoRelativePath(final IResource rsrc) {
+		// We should only be called for resources that are actually
+		// in this repository, so we can safely assume that their
+		// path prefix matches workdirPrefix. Testing that here is
+		// rather expensive so we don't bother.
+		//
+		final int pfxLen = workdirPrefix.length();
+		final String p = rsrc.getLocation().toString();
+		final int pLen = p.length();
+		if (pLen > pfxLen)
+			return p.substring(pfxLen);
+		else if (p.length() == pfxLen - 1)
+			return "";
+		return null;
 	}
 
 	/**
-- 
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

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux