]> source.dussan.org Git - jgit.git/commitdiff
Recurse into cloned submodules 98/5498/1
authorKevin Sawicki <kevin@github.com>
Mon, 2 Apr 2012 01:36:42 +0000 (18:36 -0700)
committerKevin Sawicki <kevin@github.com>
Mon, 2 Apr 2012 01:36:42 +0000 (18:36 -0700)
Iterate over all successfully cloned submodules recursively
and continue initializing and updating until no more are found.

Bug: 375426
Change-Id: Ifb99e41e2deb0c369442bca3c0f5f072dd006816

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

index b63a4158f9064e26d29e5922b1843f4bcc22ca78..906a8966fa2f15ac6e45cf5b5cb56ebe9743fb07 100644 (file)
@@ -69,6 +69,7 @@ import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.storage.file.FileBasedConfig;
 import org.eclipse.jgit.submodule.SubmoduleStatus;
 import org.eclipse.jgit.submodule.SubmoduleStatusType;
+import org.eclipse.jgit.submodule.SubmoduleWalk;
 import org.eclipse.jgit.util.SystemReader;
 import org.junit.Test;
 
@@ -303,6 +304,92 @@ public class CloneCommandTest extends RepositoryTestCase {
                assertEquals(commit, pathStatus.getIndexId());
        }
 
+       @Test
+       public void testCloneRepositoryWithNestedSubmodules() throws Exception {
+               git.checkout().setName(Constants.MASTER).call();
+
+               // Create submodule 1
+               File submodule1 = createTempDirectory("testCloneRepositoryWithNestedSubmodules1");
+               Git sub1Git = Git.init().setDirectory(submodule1).call();
+               assertNotNull(sub1Git);
+               Repository sub1 = sub1Git.getRepository();
+               assertNotNull(sub1);
+               addRepoToClose(sub1);
+
+               String file = "file.txt";
+               String path = "sub";
+
+               write(new File(sub1.getWorkTree(), file), "content");
+               sub1Git.add().addFilepattern(file).call();
+               RevCommit commit = sub1Git.commit().setMessage("create file").call();
+               assertNotNull(commit);
+
+               // Create submodule 2
+               File submodule2 = createTempDirectory("testCloneRepositoryWithNestedSubmodules2");
+               Git sub2Git = Git.init().setDirectory(submodule2).call();
+               assertNotNull(sub2Git);
+               Repository sub2 = sub2Git.getRepository();
+               assertNotNull(sub2);
+               addRepoToClose(sub2);
+
+               write(new File(sub2.getWorkTree(), file), "content");
+               sub2Git.add().addFilepattern(file).call();
+               RevCommit sub2Head = sub2Git.commit().setMessage("create file").call();
+               assertNotNull(sub2Head);
+
+               // Add submodule 2 to submodule 1
+               assertNotNull(sub1Git.submoduleAdd().setPath(path)
+                               .setURI(sub2.getDirectory().toURI().toString()).call());
+               RevCommit sub1Head = sub1Git.commit().setAll(true)
+                               .setMessage("Adding submodule").call();
+               assertNotNull(sub1Head);
+
+               // Add submodule 1 to default repository
+               assertNotNull(git.submoduleAdd().setPath(path)
+                               .setURI(sub1.getDirectory().toURI().toString()).call());
+               assertNotNull(git.commit().setAll(true).setMessage("Adding submodule")
+                               .call());
+
+               // Clone default repository and include submodules
+               File directory = createTempDirectory("testCloneRepositoryWithNestedSubmodules");
+               CloneCommand clone = Git.cloneRepository();
+               clone.setDirectory(directory);
+               clone.setCloneSubmodules(true);
+               clone.setURI(git.getRepository().getDirectory().toURI().toString());
+               Git git2 = clone.call();
+               addRepoToClose(git2.getRepository());
+               assertNotNull(git2);
+
+               assertEquals(Constants.MASTER, git2.getRepository().getBranch());
+               assertTrue(new File(git2.getRepository().getWorkTree(), path
+                               + File.separatorChar + file).exists());
+               assertTrue(new File(git2.getRepository().getWorkTree(), path
+                               + File.separatorChar + path + File.separatorChar + file)
+                               .exists());
+
+               SubmoduleStatusCommand status = new SubmoduleStatusCommand(
+                               git2.getRepository());
+               Map<String, SubmoduleStatus> statuses = status.call();
+               SubmoduleStatus pathStatus = statuses.get(path);
+               assertNotNull(pathStatus);
+               assertEquals(SubmoduleStatusType.INITIALIZED, pathStatus.getType());
+               assertEquals(sub1Head, pathStatus.getHeadId());
+               assertEquals(sub1Head, pathStatus.getIndexId());
+
+               SubmoduleWalk walk = SubmoduleWalk.forIndex(git2.getRepository());
+               assertTrue(walk.next());
+               Repository clonedSub1 = walk.getRepository();
+               assertNotNull(clonedSub1);
+               status = new SubmoduleStatusCommand(clonedSub1);
+               statuses = status.call();
+               pathStatus = statuses.get(path);
+               assertNotNull(pathStatus);
+               assertEquals(SubmoduleStatusType.INITIALIZED, pathStatus.getType());
+               assertEquals(sub2Head, pathStatus.getHeadId());
+               assertEquals(sub2Head, pathStatus.getIndexId());
+               assertFalse(walk.next());
+       }
+
        @Test
        public void testCloneWithAutoSetupRebase() throws Exception {
                File directory = createTempDirectory("testCloneRepository1");
index ef5b7291b77e4a8d9cd4cec16493221a33911417..f354de1657f1af61dabfcb7ea9d4d51323a748b6 100644 (file)
@@ -66,6 +66,7 @@ import org.eclipse.jgit.lib.RefUpdate;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.submodule.SubmoduleWalk;
 import org.eclipse.jgit.transport.FetchResult;
 import org.eclipse.jgit.transport.RefSpec;
 import org.eclipse.jgit.transport.RemoteConfig;
@@ -229,7 +230,7 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> {
                }
        }
 
-       private void cloneSubmodules(Repository clonedRepo) {
+       private void cloneSubmodules(Repository clonedRepo) throws IOException {
                SubmoduleInitCommand init = new SubmoduleInitCommand(clonedRepo);
                if (init.call().isEmpty())
                        return;
@@ -237,7 +238,14 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> {
                SubmoduleUpdateCommand update = new SubmoduleUpdateCommand(clonedRepo);
                configure(update);
                update.setProgressMonitor(monitor);
-               update.call();
+               if (!update.call().isEmpty()) {
+                       SubmoduleWalk walk = SubmoduleWalk.forIndex(clonedRepo);
+                       while (walk.next()) {
+                               Repository subRepo = walk.getRepository();
+                               if (subRepo != null)
+                                       cloneSubmodules(subRepo);
+                       }
+               }
        }
 
        private Ref findBranchToCheckout(FetchResult result) {