diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java index 0e9f6721c..ea59b1447 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java @@ -51,6 +51,7 @@ import java.io.File; import java.io.IOException; import java.util.Collections; import java.util.List; +import java.util.Map; import org.eclipse.jgit.api.ListBranchCommand.ListMode; import org.eclipse.jgit.api.errors.JGitInternalException; @@ -63,6 +64,9 @@ import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryTestCase; import org.eclipse.jgit.revwalk.RevBlob; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.submodule.SubmoduleStatus; +import org.eclipse.jgit.submodule.SubmoduleStatusType; import org.junit.Test; public class CloneCommandTest extends RepositoryTestCase { @@ -252,4 +256,47 @@ public class CloneCommandTest extends RepositoryTestCase { assertEquals(Constants.MASTER, git2.getRepository().getBranch()); } + + @Test + public void testCloneRepositoryWithSubmodules() throws Exception { + git.checkout().setName(Constants.MASTER).call(); + + String file = "file.txt"; + writeTrashFile(file, "content"); + git.add().addFilepattern(file).call(); + RevCommit commit = git.commit().setMessage("create file").call(); + + SubmoduleAddCommand command = new SubmoduleAddCommand(db); + String path = "sub"; + command.setPath(path); + String uri = db.getDirectory().toURI().toString(); + command.setURI(uri); + Repository repo = command.call(); + assertNotNull(repo); + git.add().addFilepattern(path) + .addFilepattern(Constants.DOT_GIT_MODULES).call(); + git.commit().setMessage("adding submodule").call(); + + File directory = createTempDirectory("testCloneRepositoryWithSubmodules"); + CloneCommand clone = Git.cloneRepository(); + clone.setDirectory(directory); + clone.setCloneSubmodules(true); + clone.setURI("file://" + git.getRepository().getWorkTree().getPath()); + 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()); + + SubmoduleStatusCommand status = new SubmoduleStatusCommand( + git2.getRepository()); + Map statuses = status.call(); + SubmoduleStatus pathStatus = statuses.get(path); + assertNotNull(pathStatus); + assertEquals(SubmoduleStatusType.INITIALIZED, pathStatus.getType()); + assertEquals(commit, pathStatus.getHeadId()); + assertEquals(commit, pathStatus.getIndexId()); + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java index b779c488a..ae72b770f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java @@ -94,6 +94,8 @@ public class CloneCommand extends TransportCommand { private boolean cloneAllBranches; + private boolean cloneSubmodules; + private boolean noCheckout; private Collection branchesToClone; @@ -222,9 +224,22 @@ public class CloneCommand extends TransportCommand { DirCacheCheckout co = new DirCacheCheckout(clonedRepo, dc, commit.getTree()); co.checkout(); + if (cloneSubmodules) + cloneSubmodules(clonedRepo); } } + private void cloneSubmodules(Repository clonedRepo) { + SubmoduleInitCommand init = new SubmoduleInitCommand(clonedRepo); + if (init.call().isEmpty()) + return; + + SubmoduleUpdateCommand update = new SubmoduleUpdateCommand(clonedRepo); + configure(update); + update.setProgressMonitor(monitor); + update.call(); + } + private Ref findBranchToCheckout(FetchResult result) { final Ref idHEAD = result.getAdvertisedRef(Constants.HEAD); if (idHEAD == null) @@ -356,6 +371,17 @@ public class CloneCommand extends TransportCommand { return this; } + /** + * @param cloneSubmodules + * true to initialize and update submodules. Ignored when + * {@link #setBare(boolean)} is set to true. + * @return {@code this} + */ + public CloneCommand setCloneSubmodules(boolean cloneSubmodules) { + this.cloneSubmodules = cloneSubmodules; + return this; + } + /** * @param branchesToClone * collection of branches to clone. Ignored when allSelected is