]> source.dussan.org Git - jgit.git/commitdiff
Allow explicit configuration of git directory in CloneCommand 81/37981/4
authorChristian Halstrick <christian.halstrick@sap.com>
Wed, 10 Dec 2014 16:45:52 +0000 (17:45 +0100)
committerMatthias Sohn <matthias.sohn@sap.com>
Sun, 14 Dec 2014 23:22:51 +0000 (00:22 +0100)
This feature is needed to support the new submodule layout where the
.git folder of the submodules is under .git/modules/<submodule>.

Change-Id: If5f13426cfd09b7677e23478e9700c8c25a6dae5

org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java
org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java

index de430fc94f9d0bbf4572e6a37cf42c459dacee2e..06829fa4db746ac1767c0f82fb5b586a6a5e6a40 100644 (file)
@@ -45,6 +45,7 @@ package org.eclipse.jgit.api;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -58,6 +59,7 @@ import java.util.Map;
 import org.eclipse.jgit.api.ListBranchCommand.ListMode;
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.errors.NoWorkTreeException;
 import org.eclipse.jgit.junit.RepositoryTestCase;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.lib.ConfigConstants;
@@ -135,6 +137,54 @@ public class CloneCommandTest extends RepositoryTestCase {
                                fetchRefSpec(git2.getRepository()));
        }
 
+       @Test
+       public void testCloneRepositoryExplicitGitDir() throws IOException,
+                       JGitInternalException, GitAPIException {
+               File directory = createTempDirectory("testCloneRepository");
+               CloneCommand command = Git.cloneRepository();
+               command.setDirectory(directory);
+               command.setGitDir(new File(directory, ".git"));
+               command.setURI(fileUri());
+               Git git2 = command.call();
+               assertEquals(directory, git2.getRepository().getWorkTree());
+               assertEquals(new File(directory, ".git"), git2.getRepository()
+                               .getDirectory());
+       }
+
+       @Test
+       public void testCloneRepositoryExplicitGitDirNonStd() throws IOException,
+                       JGitInternalException, GitAPIException {
+               File directory = createTempDirectory("testCloneRepository");
+               File gDir = createTempDirectory("testCloneRepository.git");
+               CloneCommand command = Git.cloneRepository();
+               command.setDirectory(directory);
+               command.setGitDir(gDir);
+               command.setURI(fileUri());
+               Git git2 = command.call();
+               assertEquals(directory, git2.getRepository().getWorkTree());
+               assertEquals(gDir, git2.getRepository()
+                               .getDirectory());
+               assertTrue(new File(directory, ".git").isFile());
+               assertFalse(new File(gDir, ".git").exists());
+       }
+
+       @Test
+       public void testCloneRepositoryExplicitGitDirBare() throws IOException,
+                       JGitInternalException, GitAPIException {
+               File gDir = createTempDirectory("testCloneRepository.git");
+               CloneCommand command = Git.cloneRepository();
+               command.setBare(true);
+               command.setGitDir(gDir);
+               command.setURI(fileUri());
+               Git git2 = command.call();
+               try {
+                       assertNull(null, git2.getRepository().getWorkTree());
+                       fail("Expected NoWorkTreeException");
+               } catch (NoWorkTreeException e) {
+                       assertEquals(gDir, git2.getRepository().getDirectory());
+               }
+       }
+
        @Test
        public void testBareCloneRepository() throws IOException,
                        JGitInternalException, GitAPIException, URISyntaxException {
index 645d3e781572de89c34018d9c303c20fc2f4ddbb..de24dadff64439b5671befff1734de79a72c5725 100644 (file)
@@ -86,6 +86,8 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> {
 
        private File directory;
 
+       private File gitDir;
+
        private boolean bare;
 
        private String remote = Constants.DEFAULT_REMOTE_NAME;
@@ -137,12 +139,19 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> {
        private Repository init(URIish u) throws GitAPIException {
                InitCommand command = Git.init();
                command.setBare(bare);
-               if (directory == null)
+               if (directory == null && gitDir == null)
                        directory = new File(u.getHumanishName(), Constants.DOT_GIT);
-               if (directory.exists() && directory.listFiles().length != 0)
+               if (directory != null && directory.exists()
+                               && directory.listFiles().length != 0)
                        throw new JGitInternalException(MessageFormat.format(
                                        JGitText.get().cloneNonEmptyDirectory, directory.getName()));
-               command.setDirectory(directory);
+               if (gitDir != null && gitDir.exists() && gitDir.listFiles().length != 0)
+                       throw new JGitInternalException(MessageFormat.format(
+                                       JGitText.get().cloneNonEmptyDirectory, gitDir.getName()));
+               if (directory != null)
+                       command.setDirectory(directory);
+               if (gitDir != null)
+                       command.setGitDir(gitDir);
                return command.call().getRepository();
        }
 
@@ -336,18 +345,47 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> {
         * @param directory
         *            the directory to clone to
         * @return this instance
+        * @throws IllegalStateException
+        *             if the combination of directory, gitDir and bare is illegal.
+        *             E.g. if for a non-bare repository directory and gitDir point
+        *             to the same directory of if for a bare repository both
+        *             directory and gitDir are specified
         */
        public CloneCommand setDirectory(File directory) {
+               validateDirs(directory, gitDir, bare);
                this.directory = directory;
                return this;
        }
 
+       /**
+        * @param gitDir
+        *            the repository meta directory
+        * @return this instance
+        * @throws IllegalStateException
+        *             if the combination of directory, gitDir and bare is illegal.
+        *             E.g. if for a non-bare repository directory and gitDir point
+        *             to the same directory of if for a bare repository both
+        *             directory and gitDir are specified
+        * @since 3.6
+        */
+       public CloneCommand setGitDir(File gitDir) {
+               validateDirs(directory, gitDir, bare);
+               this.gitDir = gitDir;
+               return this;
+       }
+
        /**
         * @param bare
         *            whether the cloned repository is bare or not
         * @return this instance
+        * @throws IllegalStateException
+        *             if the combination of directory, gitDir and bare is illegal.
+        *             E.g. if for a non-bare repository directory and gitDir point
+        *             to the same directory of if for a bare repository both
+        *             directory and gitDir are specified
         */
-       public CloneCommand setBare(boolean bare) {
+       public CloneCommand setBare(boolean bare) throws IllegalStateException {
+               validateDirs(directory, gitDir, bare);
                this.bare = bare;
                return this;
        }
@@ -438,4 +476,21 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> {
                this.noCheckout = noCheckout;
                return this;
        }
+
+       private static void validateDirs(File directory, File gitDir, boolean bare)
+                       throws IllegalStateException {
+               if (directory != null) {
+                       if (bare) {
+                               if (gitDir != null && !gitDir.equals(directory))
+                                       throw new IllegalStateException(MessageFormat.format(
+                                                       JGitText.get().initFailedBareRepoDifferentDirs,
+                                                       gitDir, directory));
+                       } else {
+                               if (gitDir != null && gitDir.equals(directory))
+                                       throw new IllegalStateException(MessageFormat.format(
+                                                       JGitText.get().initFailedNonBareRepoSameDirs,
+                                                       gitDir, directory));
+                       }
+               }
+       }
 }