summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorRobin Stocker2012-01-22 07:22:44 (EST)
committer Dariusz Luksza2012-01-22 07:22:44 (EST)
commit03a111b4c460bb1443f50de3294da9424de0dbcd (patch)
tree9174f912ff8633c82ab8da233f3a264142718481
parent1ee3fa4770d8e74b7c8b6f1ce2d34da51db91020 (diff)
downloadegit-03a111b4c460bb1443f50de3294da9424de0dbcd.zip
egit-03a111b4c460bb1443f50de3294da9424de0dbcd.tar.gz
egit-03a111b4c460bb1443f50de3294da9424de0dbcd.tar.bz2
Skip clone for import of project from existing reporefs/changes/80/4780/5
Before, we would abort importing when the target directory already existed. Now we check if the target directory contains a repository that was cloned from the same URL and if so, skip the clone step. When the target exists and is not a repo or not for the same URL, we still abort. Bug: 366207 Change-Id: I591e86fc910c951437881bc1f93fba4c4d466c50 Signed-off-by: Robin Stocker <robin@nibor.org> Signed-off-by: Dariusz Luksza <dariusz@luksza.org>
-rw-r--r--org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/GitProjectSetCapabilityTest.java54
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties2
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/internal/ProjectReferenceImporter.java79
3 files changed, 117 insertions, 18 deletions
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/GitProjectSetCapabilityTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/GitProjectSetCapabilityTest.java
index 78457c0..0ade99b 100644
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/GitProjectSetCapabilityTest.java
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/GitProjectSetCapabilityTest.java
@@ -11,6 +11,7 @@ package org.eclipse.egit.core.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.File;
import java.util.ArrayList;
@@ -34,6 +35,7 @@ import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepository;
import org.eclipse.jgit.util.FileUtils;
import org.eclipse.team.core.ProjectSetSerializationContext;
+import org.eclipse.team.core.TeamException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -191,6 +193,50 @@ public class GitProjectSetCapabilityTest {
assertEquals("stable", xbMapping.getRepository().getBranch());
}
+ @Test
+ public void testImportWithMultipleCallsForSameDestinationRepo() throws Exception {
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ IPath reposPath = root.getLocation().append("repos");
+ pathsToClean.add(reposPath.toFile());
+
+ IPath xPath = reposPath.append("x");
+ IProject xaProject = createProject(xPath, "xa");
+ IProject xbProject = createProject(xPath, "xb");
+ String url = createUrl(xPath);
+ createRepository(xPath, url, "stable");
+ xaProject.delete(false, true, null);
+ xbProject.delete(false, true, null);
+
+ String xaReference = createProjectReference(xPath, "master", "xa");
+ String xbReference = createProjectReference(xPath, "master", "xb");
+
+ // This should work because there is not yet a repo at the destination
+ capability.addToWorkspace(new String[] { xaReference },
+ new ProjectSetSerializationContext(),
+ new NullProgressMonitor());
+
+ // This should work because the repo that is already there is for the
+ // same remote URL. It's assumed to be ok and will skip cloning and
+ // directly import the project.
+ capability.addToWorkspace(new String[] { xbReference },
+ new ProjectSetSerializationContext(),
+ new NullProgressMonitor());
+
+ pathsToClean.add(root.getLocation().append("x").toFile());
+
+ IPath otherPathWithX = reposPath.append("other").append("x");
+ String otherReferenceWithDifferentUrl = createProjectReference(otherPathWithX, "master", "xb");
+
+ try {
+ capability.addToWorkspace(new String[] { otherReferenceWithDifferentUrl },
+ new ProjectSetSerializationContext(),
+ new NullProgressMonitor());
+ fail("Should throw TeamException when a repo exists at the place but doesn't have the same URL.");
+ } catch (TeamException e) {
+ // This is expected
+ }
+ }
+
private IProject createProject(String name) throws CoreException {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IProject p = root.getProject(name);
@@ -237,4 +283,12 @@ public class GitProjectSetCapabilityTest {
project.getProject(), gitDir);
operation.execute(null);
}
+
+ private static String createProjectReference(IPath repoPath, String branch, String projectPath) {
+ return "1.0," + createUrl(repoPath) + "," + branch + "," + projectPath;
+ }
+
+ private static String createUrl(IPath repoPath) {
+ return repoPath.toFile().toURI().toString();
+ }
}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties b/org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties
index 7599c69..b06b5ee 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties
@@ -80,7 +80,7 @@ The resource cannot be moved, renamed or deleted due to an internal error.
Error_CanonicalFile=Unable to determine a canonical file path.
ProjectReference_InvalidTokensCount={0} tokens expected in project reference but {1} had been found: {2}
-GitProjectSetCapability_CloneToExistingDirectory=Destination directory {0} exists. Don''t clone {1} from {2} to prevent data loss.
+GitProjectSetCapability_CloneToExistingDirectory=Destination directory {0} already exists and doesn't contain the expected Git repository. Won''t clone {1} from {2} to prevent data loss.
GitProjectSetCapability_ExportCouldNotGetBranch=Could not get current branch from repository of project {0}.
GitProjectSetCapability_ExportNoRemote=No remote URL configured for current branch in repository of project {0}.
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/ProjectReferenceImporter.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/ProjectReferenceImporter.java
index a55778a..b030c74 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/ProjectReferenceImporter.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/ProjectReferenceImporter.java
@@ -9,6 +9,7 @@
package org.eclipse.egit.core.internal;
import java.io.File;
+import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URISyntaxException;
import java.util.ArrayList;
@@ -35,7 +36,10 @@ import org.eclipse.egit.core.CoreText;
import org.eclipse.egit.core.ProjectReference;
import org.eclipse.egit.core.op.CloneOperation;
import org.eclipse.egit.core.op.ConnectProviderOperation;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.storage.file.FileRepository;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.TeamException;
@@ -80,27 +84,35 @@ public class ProjectReferenceImporter {
final IPath workDir = getWorkingDir(gitUrl, branch,
branches.keySet());
+ final File repositoryPath = workDir.append(
+ Constants.DOT_GIT_EXT).toFile();
+
+ boolean shouldClone = true;
+
if (workDir.toFile().exists()) {
- final Collection<String> projectNames = new LinkedList<String>();
- for (final ProjectReference projectReference : projects)
- projectNames.add(projectReference.getProjectDir());
- throw new TeamException(
- NLS.bind(
- CoreText.GitProjectSetCapability_CloneToExistingDirectory,
- new Object[] { workDir, projectNames,
- gitUrl }));
+ if (repositoryAlreadyExistsForUrl(repositoryPath, gitUrl))
+ shouldClone = false;
+ else {
+ final Collection<String> projectNames = new LinkedList<String>();
+ for (final ProjectReference projectReference : projects)
+ projectNames.add(projectReference.getProjectDir());
+ throw new TeamException(
+ NLS.bind(
+ CoreText.GitProjectSetCapability_CloneToExistingDirectory,
+ new Object[] { workDir, projectNames,
+ gitUrl }));
+ }
}
try {
- int timeout = 60;
- String refName = Constants.R_HEADS + branch;
- final CloneOperation cloneOperation = new CloneOperation(
- gitUrl, true, null, workDir.toFile(), refName,
- Constants.DEFAULT_REMOTE_NAME, timeout);
- cloneOperation.run(monitor);
-
- final File repositoryPath = workDir.append(
- Constants.DOT_GIT_EXT).toFile();
+ if (shouldClone) {
+ int timeout = 60;
+ String refName = Constants.R_HEADS + branch;
+ final CloneOperation cloneOperation = new CloneOperation(
+ gitUrl, true, null, workDir.toFile(), refName,
+ Constants.DEFAULT_REMOTE_NAME, timeout);
+ cloneOperation.run(monitor);
+ }
Activator.getDefault().getRepositoryUtil()
.addConfiguredRepository(repositoryPath);
@@ -176,6 +188,39 @@ public class ProjectReferenceImporter {
return workDir;
}
+ private static boolean repositoryAlreadyExistsForUrl(File repositoryPath,
+ URIish gitUrl) {
+ if (repositoryPath.exists()) {
+ try {
+ FileRepository existingRepository = new FileRepository(
+ repositoryPath);
+ boolean exists = containsRemoteForUrl(
+ existingRepository.getConfig(), gitUrl);
+ existingRepository.close();
+ return exists;
+ } catch (IOException e) {
+ return false;
+ } catch (URISyntaxException e) {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ private static boolean containsRemoteForUrl(Config config, URIish url) throws URISyntaxException {
+ Set<String> remotes = config.getSubsections(ConfigConstants.CONFIG_REMOTE_SECTION);
+ for (String remote : remotes) {
+ String remoteUrl = config.getString(
+ ConfigConstants.CONFIG_REMOTE_SECTION,
+ remote,
+ ConfigConstants.CONFIG_KEY_URL);
+ URIish existingUrl = new URIish(remoteUrl);
+ if (existingUrl.equals(url))
+ return true;
+ }
+ return false;
+ }
+
private List<IProject> importProjects(final Set<ProjectReference> projects,
final IPath workDir, final File repositoryPath,
final IProgressMonitor monitor) throws TeamException {