View Javadoc
1   /*
2    * Copyright (C) 2011, 2013 Chris Aniszczyk <caniszczyk@gmail.com> and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  package org.eclipse.jgit.api;
11  
12  import static org.junit.Assert.assertEquals;
13  import static org.junit.Assert.assertFalse;
14  import static org.junit.Assert.assertNotNull;
15  import static org.junit.Assert.assertNull;
16  import static org.junit.Assert.assertTrue;
17  import static org.junit.Assert.fail;
18  
19  import java.io.File;
20  import java.io.IOException;
21  import java.net.URISyntaxException;
22  import java.util.Collections;
23  import java.util.List;
24  import java.util.Map;
25  
26  import org.eclipse.jgit.api.ListBranchCommand.ListMode;
27  import org.eclipse.jgit.api.errors.GitAPIException;
28  import org.eclipse.jgit.api.errors.JGitInternalException;
29  import org.eclipse.jgit.errors.NoWorkTreeException;
30  import org.eclipse.jgit.junit.RepositoryTestCase;
31  import org.eclipse.jgit.junit.TestRepository;
32  import org.eclipse.jgit.lib.BranchConfig.BranchRebaseMode;
33  import org.eclipse.jgit.lib.ConfigConstants;
34  import org.eclipse.jgit.lib.Constants;
35  import org.eclipse.jgit.lib.ObjectId;
36  import org.eclipse.jgit.lib.Ref;
37  import org.eclipse.jgit.lib.RefUpdate;
38  import org.eclipse.jgit.lib.Repository;
39  import org.eclipse.jgit.lib.StoredConfig;
40  import org.eclipse.jgit.revwalk.RevBlob;
41  import org.eclipse.jgit.revwalk.RevCommit;
42  import org.eclipse.jgit.submodule.SubmoduleStatus;
43  import org.eclipse.jgit.submodule.SubmoduleStatusType;
44  import org.eclipse.jgit.submodule.SubmoduleWalk;
45  import org.eclipse.jgit.transport.RefSpec;
46  import org.eclipse.jgit.transport.RemoteConfig;
47  import org.eclipse.jgit.transport.URIish;
48  import org.eclipse.jgit.util.SystemReader;
49  import org.junit.Test;
50  
51  public class CloneCommandTest extends RepositoryTestCase {
52  
53  	private Git git;
54  
55  	private TestRepository<Repository> tr;
56  
57  	@Override
58  	public void setUp() throws Exception {
59  		super.setUp();
60  		tr = new TestRepository<>(db);
61  
62  		git = new Git(db);
63  		// commit something
64  		writeTrashFile("Test.txt", "Hello world");
65  		git.add().addFilepattern("Test.txt").call();
66  		git.commit().setMessage("Initial commit").call();
67  		Ref head = git.tag().setName("tag-initial").setMessage("Tag initial")
68  				.call();
69  
70  		// create a test branch and switch to it
71  		git.checkout().setCreateBranch(true).setName("test").call();
72  		// create a non-standard ref
73  		RefUpdate ru = db.updateRef("refs/meta/foo/bar");
74  		ru.setNewObjectId(head.getObjectId());
75  		ru.update();
76  
77  		// commit something on the test branch
78  		writeTrashFile("Test.txt", "Some change");
79  		git.add().addFilepattern("Test.txt").call();
80  		git.commit().setMessage("Second commit").call();
81  		RevBlob blob = tr.blob("blob-not-in-master-branch");
82  		git.tag().setName("tag-for-blob").setObjectId(blob).call();
83  	}
84  
85  	@Test
86  	public void testCloneRepository() throws IOException,
87  			JGitInternalException, GitAPIException, URISyntaxException {
88  		File directory = createTempDirectory("testCloneRepository");
89  		CloneCommand command = Git.cloneRepository();
90  		command.setDirectory(directory);
91  		command.setURI(fileUri());
92  		Git git2 = command.call();
93  		addRepoToClose(git2.getRepository());
94  		assertNotNull(git2);
95  		ObjectId id = git2.getRepository().resolve("tag-for-blob");
96  		assertNotNull(id);
97  		assertEquals(git2.getRepository().getFullBranch(), "refs/heads/test");
98  		assertEquals(
99  				"origin",
100 				git2.getRepository()
101 						.getConfig()
102 						.getString(ConfigConstants.CONFIG_BRANCH_SECTION,
103 								"test", ConfigConstants.CONFIG_KEY_REMOTE));
104 		assertEquals(
105 				"refs/heads/test",
106 				git2.getRepository()
107 						.getConfig()
108 						.getString(ConfigConstants.CONFIG_BRANCH_SECTION,
109 								"test", ConfigConstants.CONFIG_KEY_MERGE));
110 		assertEquals(2, git2.branchList().setListMode(ListMode.REMOTE).call()
111 				.size());
112 		assertEquals(new RefSpec("+refs/heads/*:refs/remotes/origin/*"),
113 				fetchRefSpec(git2.getRepository()));
114 	}
115 
116 	@Test
117 	public void testCloneRepositoryExplicitGitDir() throws IOException,
118 			JGitInternalException, GitAPIException {
119 		File directory = createTempDirectory("testCloneRepository");
120 		CloneCommand command = Git.cloneRepository();
121 		command.setDirectory(directory);
122 		command.setGitDir(new File(directory, Constants.DOT_GIT));
123 		command.setURI(fileUri());
124 		Git git2 = command.call();
125 		addRepoToClose(git2.getRepository());
126 		assertEquals(directory, git2.getRepository().getWorkTree());
127 		assertEquals(new File(directory, Constants.DOT_GIT), git2.getRepository()
128 				.getDirectory());
129 	}
130 
131 	@Test
132 	public void testCloneRepositoryDefaultDirectory()
133 			throws URISyntaxException, JGitInternalException {
134 		CloneCommand command = Git.cloneRepository().setURI(fileUri());
135 
136 		command.verifyDirectories(new URIish(fileUri()));
137 		File directory = command.getDirectory();
138 		assertEquals(git.getRepository().getWorkTree().getName(), directory.getName());
139 	}
140 
141 	@Test
142 	public void testCloneBareRepositoryDefaultDirectory()
143 			throws URISyntaxException, JGitInternalException {
144 		CloneCommand command = Git.cloneRepository().setURI(fileUri()).setBare(true);
145 
146 		command.verifyDirectories(new URIish(fileUri()));
147 		File directory = command.getDirectory();
148 		assertEquals(git.getRepository().getWorkTree().getName() + Constants.DOT_GIT_EXT, directory.getName());
149 	}
150 
151 	@Test
152 	public void testCloneRepositoryExplicitGitDirNonStd() throws IOException,
153 			JGitInternalException, GitAPIException {
154 		File directory = createTempDirectory("testCloneRepository");
155 		File gDir = createTempDirectory("testCloneRepository.git");
156 		CloneCommand command = Git.cloneRepository();
157 		command.setDirectory(directory);
158 		command.setGitDir(gDir);
159 		command.setURI(fileUri());
160 		Git git2 = command.call();
161 		addRepoToClose(git2.getRepository());
162 		assertEquals(directory, git2.getRepository().getWorkTree());
163 		assertEquals(gDir, git2.getRepository()
164 				.getDirectory());
165 		assertTrue(new File(directory, Constants.DOT_GIT).isFile());
166 		assertFalse(new File(gDir, Constants.DOT_GIT).exists());
167 	}
168 
169 	@Test
170 	public void testCloneRepositoryExplicitGitDirBare() throws IOException,
171 			JGitInternalException, GitAPIException {
172 		File gDir = createTempDirectory("testCloneRepository.git");
173 		CloneCommand command = Git.cloneRepository();
174 		command.setBare(true);
175 		command.setGitDir(gDir);
176 		command.setURI(fileUri());
177 		Git git2 = command.call();
178 		addRepoToClose(git2.getRepository());
179 		try {
180 			assertNull(null, git2.getRepository().getWorkTree());
181 			fail("Expected NoWorkTreeException");
182 		} catch (NoWorkTreeException e) {
183 			assertEquals(gDir, git2.getRepository().getDirectory());
184 		}
185 	}
186 
187 	@Test
188 	public void testBareCloneRepository() throws IOException,
189 			JGitInternalException, GitAPIException, URISyntaxException {
190 		File directory = createTempDirectory("testCloneRepository_bare");
191 		CloneCommand command = Git.cloneRepository();
192 		command.setBare(true);
193 		command.setDirectory(directory);
194 		command.setURI(fileUri());
195 		Git git2 = command.call();
196 		addRepoToClose(git2.getRepository());
197 		assertEquals(new RefSpec("+refs/heads/*:refs/heads/*"),
198 				fetchRefSpec(git2.getRepository()));
199 	}
200 
201 	@Test
202 	public void testCloneRepositoryCustomRemote() throws Exception {
203 		File directory = createTempDirectory("testCloneRemoteUpstream");
204 		CloneCommand command = Git.cloneRepository();
205 		command.setDirectory(directory);
206 		command.setRemote("upstream");
207 		command.setURI(fileUri());
208 		Git git2 = command.call();
209 		addRepoToClose(git2.getRepository());
210 		assertEquals("+refs/heads/*:refs/remotes/upstream/*",
211 				git2.getRepository()
212 					.getConfig()
213 					.getStringList("remote", "upstream",
214 							"fetch")[0]);
215 		assertEquals("upstream",
216 				git2.getRepository()
217 					.getConfig()
218 					.getString("branch", "test", "remote"));
219 		assertEquals(db.resolve("test"),
220 				git2.getRepository().resolve("upstream/test"));
221 	}
222 
223 	@Test
224 	public void testBareCloneRepositoryCustomRemote() throws Exception {
225 		File directory = createTempDirectory("testCloneRemoteUpstream_bare");
226 		CloneCommand command = Git.cloneRepository();
227 		command.setBare(true);
228 		command.setDirectory(directory);
229 		command.setRemote("upstream");
230 		command.setURI(fileUri());
231 		Git git2 = command.call();
232 		addRepoToClose(git2.getRepository());
233 		assertEquals("+refs/heads/*:refs/heads/*",
234 				git2.getRepository()
235 					.getConfig()
236 					.getStringList("remote", "upstream",
237 							"fetch")[0]);
238 		assertEquals("upstream",
239 				git2.getRepository()
240 					.getConfig()
241 					.getString("branch", "test", "remote"));
242 		assertNull(git2.getRepository().resolve("upstream/test"));
243 	}
244 
245 	@Test
246 	public void testBareCloneRepositoryNullRemote() throws Exception {
247 		File directory = createTempDirectory("testCloneRemoteNull_bare");
248 		CloneCommand command = Git.cloneRepository();
249 		command.setBare(true);
250 		command.setDirectory(directory);
251 		command.setRemote(null);
252 		command.setURI(fileUri());
253 		Git git2 = command.call();
254 		addRepoToClose(git2.getRepository());
255 		assertEquals("+refs/heads/*:refs/heads/*", git2.getRepository()
256 				.getConfig().getStringList("remote", "origin", "fetch")[0]);
257 		assertEquals("origin", git2.getRepository().getConfig()
258 				.getString("branch", "test", "remote"));
259 	}
260 
261 	public static RefSpec fetchRefSpec(Repository r) throws URISyntaxException {
262 		RemoteConfig remoteConfig =
263 				new RemoteConfig(r.getConfig(), Constants.DEFAULT_REMOTE_NAME);
264 		return remoteConfig.getFetchRefSpecs().get(0);
265 	}
266 
267 	@Test
268 	public void testCloneRepositoryWithBranch() throws IOException,
269 			JGitInternalException, GitAPIException {
270 		File directory = createTempDirectory("testCloneRepositoryWithBranch");
271 		CloneCommand command = Git.cloneRepository();
272 		command.setBranch("refs/heads/master");
273 		command.setDirectory(directory);
274 		command.setURI(fileUri());
275 		Git git2 = command.call();
276 		addRepoToClose(git2.getRepository());
277 
278 		assertNotNull(git2);
279 		assertEquals(git2.getRepository().getFullBranch(), "refs/heads/master");
280 		assertEquals(
281 				"refs/heads/master, refs/remotes/origin/master, refs/remotes/origin/test",
282 				allRefNames(git2.branchList().setListMode(ListMode.ALL).call()));
283 
284 		// Same thing, but now without checkout
285 		directory = createTempDirectory("testCloneRepositoryWithBranch_bare");
286 		command = Git.cloneRepository();
287 		command.setBranch("refs/heads/master");
288 		command.setDirectory(directory);
289 		command.setURI(fileUri());
290 		command.setNoCheckout(true);
291 		git2 = command.call();
292 		addRepoToClose(git2.getRepository());
293 
294 		assertNotNull(git2);
295 		assertEquals(git2.getRepository().getFullBranch(), "refs/heads/master");
296 		assertEquals("refs/remotes/origin/master, refs/remotes/origin/test",
297 				allRefNames(git2.branchList().setListMode(ListMode.ALL).call()));
298 
299 		// Same thing, but now test with bare repo
300 		directory = createTempDirectory("testCloneRepositoryWithBranch_bare");
301 		command = Git.cloneRepository();
302 		command.setBranch("refs/heads/master");
303 		command.setDirectory(directory);
304 		command.setURI(fileUri());
305 		command.setBare(true);
306 		git2 = command.call();
307 		addRepoToClose(git2.getRepository());
308 
309 		assertNotNull(git2);
310 		assertEquals(git2.getRepository().getFullBranch(), "refs/heads/master");
311 		assertEquals("refs/heads/master, refs/heads/test", allRefNames(git2
312 				.branchList().setListMode(ListMode.ALL).call()));
313 	}
314 
315 	@Test
316 	public void testCloneRepositoryWithBranchShortName() throws Exception {
317 		File directory = createTempDirectory("testCloneRepositoryWithBranch");
318 		CloneCommand command = Git.cloneRepository();
319 		command.setBranch("test");
320 		command.setDirectory(directory);
321 		command.setURI(fileUri());
322 		Git git2 = command.call();
323 		addRepoToClose(git2.getRepository());
324 
325 		assertNotNull(git2);
326 		assertEquals("refs/heads/test", git2.getRepository().getFullBranch());
327 	}
328 
329 	@Test
330 	public void testCloneRepositoryWithTagName() throws Exception {
331 		File directory = createTempDirectory("testCloneRepositoryWithBranch");
332 		CloneCommand command = Git.cloneRepository();
333 		command.setBranch("tag-initial");
334 		command.setDirectory(directory);
335 		command.setURI(fileUri());
336 		Git git2 = command.call();
337 		addRepoToClose(git2.getRepository());
338 
339 		assertNotNull(git2);
340 		ObjectId taggedCommit = db.resolve("tag-initial^{commit}");
341 		assertEquals(taggedCommit.name(), git2
342 				.getRepository().getFullBranch());
343 	}
344 
345 	@Test
346 	public void testCloneRepositoryOnlyOneBranch() throws Exception {
347 		File directory = createTempDirectory("testCloneRepositoryWithBranch");
348 		CloneCommand command = Git.cloneRepository();
349 		command.setBranch("refs/heads/master");
350 		command.setBranchesToClone(Collections
351 				.singletonList("refs/heads/master"));
352 		command.setDirectory(directory);
353 		command.setURI(fileUri());
354 		Git git2 = command.call();
355 		addRepoToClose(git2.getRepository());
356 		assertNotNull(git2);
357 		assertNull(git2.getRepository().resolve("tag-for-blob"));
358 		assertNotNull(git2.getRepository().resolve("tag-initial"));
359 		assertEquals(git2.getRepository().getFullBranch(), "refs/heads/master");
360 		assertEquals("refs/remotes/origin/master", allRefNames(git2
361 				.branchList().setListMode(ListMode.REMOTE).call()));
362 		RemoteConfig cfg = new RemoteConfig(git2.getRepository().getConfig(),
363 				Constants.DEFAULT_REMOTE_NAME);
364 		List<RefSpec> specs = cfg.getFetchRefSpecs();
365 		assertEquals(1, specs.size());
366 		assertEquals(
367 				new RefSpec("+refs/heads/master:refs/remotes/origin/master"),
368 				specs.get(0));
369 	}
370 
371 	@Test
372 	public void testBareCloneRepositoryOnlyOneBranch() throws Exception {
373 		File directory = createTempDirectory(
374 				"testCloneRepositoryWithBranch_bare");
375 		CloneCommand command = Git.cloneRepository();
376 		command.setBranch("refs/heads/master");
377 		command.setBranchesToClone(Collections
378 				.singletonList("refs/heads/master"));
379 		command.setDirectory(directory);
380 		command.setURI(fileUri());
381 		command.setBare(true);
382 		Git git2 = command.call();
383 		addRepoToClose(git2.getRepository());
384 		assertNotNull(git2);
385 		assertNull(git2.getRepository().resolve("tag-for-blob"));
386 		assertNotNull(git2.getRepository().resolve("tag-initial"));
387 		assertEquals(git2.getRepository().getFullBranch(), "refs/heads/master");
388 		assertEquals("refs/heads/master", allRefNames(git2.branchList()
389 				.setListMode(ListMode.ALL).call()));
390 		RemoteConfig cfg = new RemoteConfig(git2.getRepository().getConfig(),
391 				Constants.DEFAULT_REMOTE_NAME);
392 		List<RefSpec> specs = cfg.getFetchRefSpecs();
393 		assertEquals(1, specs.size());
394 		assertEquals(
395 				new RefSpec("+refs/heads/master:refs/heads/master"),
396 				specs.get(0));
397 	}
398 
399 	@Test
400 	public void testBareCloneRepositoryMirror() throws Exception {
401 		File directory = createTempDirectory(
402 				"testCloneRepositoryWithBranch_mirror");
403 		CloneCommand command = Git.cloneRepository();
404 		command.setBranch("refs/heads/master");
405 		command.setMirror(true); // implies bare repository
406 		command.setDirectory(directory);
407 		command.setURI(fileUri());
408 		Git git2 = command.call();
409 		addRepoToClose(git2.getRepository());
410 		assertNotNull(git2);
411 		assertTrue(git2.getRepository().isBare());
412 		assertNotNull(git2.getRepository().resolve("tag-for-blob"));
413 		assertNotNull(git2.getRepository().resolve("tag-initial"));
414 		assertEquals(git2.getRepository().getFullBranch(), "refs/heads/master");
415 		assertEquals("refs/heads/master, refs/heads/test", allRefNames(
416 				git2.branchList().setListMode(ListMode.ALL).call()));
417 		assertNotNull(git2.getRepository().exactRef("refs/meta/foo/bar"));
418 		RemoteConfig cfg = new RemoteConfig(git2.getRepository().getConfig(),
419 				Constants.DEFAULT_REMOTE_NAME);
420 		List<RefSpec> specs = cfg.getFetchRefSpecs();
421 		assertEquals(1, specs.size());
422 		assertEquals(new RefSpec("+refs/*:refs/*"),
423 				specs.get(0));
424 	}
425 
426 	@Test
427 	public void testCloneRepositoryOnlyOneTag() throws Exception {
428 		File directory = createTempDirectory("testCloneRepositoryWithBranch");
429 		CloneCommand command = Git.cloneRepository();
430 		command.setBranch("tag-initial");
431 		command.setBranchesToClone(
432 				Collections.singletonList("refs/tags/tag-initial"));
433 		command.setDirectory(directory);
434 		command.setURI(fileUri());
435 		Git git2 = command.call();
436 		addRepoToClose(git2.getRepository());
437 		assertNotNull(git2);
438 		assertNull(git2.getRepository().resolve("tag-for-blob"));
439 		assertNull(git2.getRepository().resolve("refs/heads/master"));
440 		assertNotNull(git2.getRepository().resolve("tag-initial"));
441 		ObjectId taggedCommit = db.resolve("tag-initial^{commit}");
442 		assertEquals(taggedCommit.name(), git2.getRepository().getFullBranch());
443 		RemoteConfig cfg = new RemoteConfig(git2.getRepository().getConfig(),
444 				Constants.DEFAULT_REMOTE_NAME);
445 		List<RefSpec> specs = cfg.getFetchRefSpecs();
446 		assertEquals(1, specs.size());
447 		assertEquals(
448 				new RefSpec("+refs/tags/tag-initial:refs/tags/tag-initial"),
449 				specs.get(0));
450 	}
451 
452 	@Test
453 	public void testCloneRepositoryAllBranchesTakesPreference()
454 			throws Exception {
455 		File directory = createTempDirectory(
456 				"testCloneRepositoryAllBranchesTakesPreference");
457 		CloneCommand command = Git.cloneRepository();
458 		command.setCloneAllBranches(true);
459 		command.setBranchesToClone(
460 				Collections.singletonList("refs/heads/test"));
461 		command.setDirectory(directory);
462 		command.setURI(fileUri());
463 		Git git2 = command.call();
464 		addRepoToClose(git2.getRepository());
465 		assertNotNull(git2);
466 		assertEquals(git2.getRepository().getFullBranch(), "refs/heads/test");
467 		// Expect both remote branches to exist; setCloneAllBranches(true)
468 		// should override any setBranchesToClone().
469 		assertNotNull(
470 				git2.getRepository().resolve("refs/remotes/origin/master"));
471 		assertNotNull(git2.getRepository().resolve("refs/remotes/origin/test"));
472 		RemoteConfig cfg = new RemoteConfig(git2.getRepository().getConfig(),
473 				Constants.DEFAULT_REMOTE_NAME);
474 		List<RefSpec> specs = cfg.getFetchRefSpecs();
475 		assertEquals(1, specs.size());
476 		assertEquals(new RefSpec("+refs/heads/*:refs/remotes/origin/*"),
477 				specs.get(0));
478 	}
479 
480 	@Test
481 	public void testCloneRepositoryAllBranchesIndependent() throws Exception {
482 		File directory = createTempDirectory(
483 				"testCloneRepositoryAllBranchesIndependent");
484 		CloneCommand command = Git.cloneRepository();
485 		command.setCloneAllBranches(true);
486 		command.setBranchesToClone(
487 				Collections.singletonList("refs/heads/test"));
488 		command.setCloneAllBranches(false);
489 		command.setDirectory(directory);
490 		command.setURI(fileUri());
491 		Git git2 = command.call();
492 		addRepoToClose(git2.getRepository());
493 		assertNotNull(git2);
494 		assertEquals(git2.getRepository().getFullBranch(), "refs/heads/test");
495 		// Expect only the test branch; allBranches was re-set to false
496 		assertNull(git2.getRepository().resolve("refs/remotes/origin/master"));
497 		assertNotNull(git2.getRepository().resolve("refs/remotes/origin/test"));
498 		RemoteConfig cfg = new RemoteConfig(git2.getRepository().getConfig(),
499 				Constants.DEFAULT_REMOTE_NAME);
500 		List<RefSpec> specs = cfg.getFetchRefSpecs();
501 		assertEquals(1, specs.size());
502 		assertEquals(new RefSpec("+refs/heads/test:refs/remotes/origin/test"),
503 				specs.get(0));
504 	}
505 
506 	public static String allRefNames(List<Ref> refs) {
507 		StringBuilder sb = new StringBuilder();
508 		for (Ref f : refs) {
509 			if (sb.length() > 0)
510 				sb.append(", ");
511 			sb.append(f.getName());
512 		}
513 		return sb.toString();
514 	}
515 
516 	@Test
517 	public void testCloneRepositoryWhenDestinationDirectoryExistsAndIsNotEmpty()
518 			throws IOException, JGitInternalException, GitAPIException {
519 		String dirName = "testCloneTargetDirectoryNotEmpty";
520 		File directory = createTempDirectory(dirName);
521 		CloneCommand command = Git.cloneRepository();
522 		command.setDirectory(directory);
523 		command.setURI(fileUri());
524 		Git git2 = command.call();
525 		addRepoToClose(git2.getRepository());
526 		assertNotNull(git2);
527 		// clone again
528 		command = Git.cloneRepository();
529 		command.setDirectory(directory);
530 		command.setURI(fileUri());
531 		try {
532 			git2 = command.call();
533 			// we shouldn't get here
534 			fail("destination directory already exists and is not an empty folder, cloning should fail");
535 		} catch (JGitInternalException e) {
536 			assertTrue(e.getMessage().contains("not an empty directory"));
537 			assertTrue(e.getMessage().contains(dirName));
538 		}
539 	}
540 
541 	@Test
542 	public void testCloneRepositoryWithMultipleHeadBranches() throws Exception {
543 		git.checkout().setName(Constants.MASTER).call();
544 		git.branchCreate().setName("a").call();
545 
546 		File directory = createTempDirectory("testCloneRepositoryWithMultipleHeadBranches");
547 		CloneCommand clone = Git.cloneRepository();
548 		clone.setDirectory(directory);
549 		clone.setURI(fileUri());
550 		Git git2 = clone.call();
551 		addRepoToClose(git2.getRepository());
552 		assertNotNull(git2);
553 
554 		assertEquals(Constants.MASTER, git2.getRepository().getBranch());
555 	}
556 
557 	@Test
558 	public void testCloneRepositoryWithSubmodules() throws Exception {
559 		git.checkout().setName(Constants.MASTER).call();
560 
561 		String file = "file.txt";
562 		writeTrashFile(file, "content");
563 		git.add().addFilepattern(file).call();
564 		RevCommit commit = git.commit().setMessage("create file").call();
565 
566 		SubmoduleAddCommand command = new SubmoduleAddCommand(db);
567 		String path = "sub";
568 		command.setPath(path);
569 		String uri = db.getDirectory().toURI().toString();
570 		command.setURI(uri);
571 		Repository repo = command.call();
572 		assertNotNull(repo);
573 		addRepoToClose(repo);
574 		git.add().addFilepattern(path)
575 				.addFilepattern(Constants.DOT_GIT_MODULES).call();
576 		git.commit().setMessage("adding submodule").call();
577 		try (SubmoduleWalk walk = SubmoduleWalk.forIndex(git.getRepository())) {
578 			assertTrue(walk.next());
579 			Repository subRepo = walk.getRepository();
580 			addRepoToClose(subRepo);
581 			assertNotNull(subRepo);
582 			assertEquals(
583 					new File(git.getRepository().getWorkTree(), walk.getPath()),
584 					subRepo.getWorkTree());
585 			assertEquals(new File(new File(git.getRepository().getDirectory(),
586 					"modules"), walk.getPath()), subRepo.getDirectory());
587 		}
588 
589 		File directory = createTempDirectory("testCloneRepositoryWithSubmodules");
590 		CloneCommand clone = Git.cloneRepository();
591 		clone.setDirectory(directory);
592 		clone.setCloneSubmodules(true);
593 		clone.setURI(fileUri());
594 		Git git2 = clone.call();
595 		addRepoToClose(git2.getRepository());
596 		assertNotNull(git2);
597 
598 		assertEquals(Constants.MASTER, git2.getRepository().getBranch());
599 		assertTrue(new File(git2.getRepository().getWorkTree(), path
600 				+ File.separatorChar + file).exists());
601 
602 		SubmoduleStatusCommand status = new SubmoduleStatusCommand(
603 				git2.getRepository());
604 		Map<String, SubmoduleStatus> statuses = status.call();
605 		SubmoduleStatus pathStatus = statuses.get(path);
606 		assertNotNull(pathStatus);
607 		assertEquals(SubmoduleStatusType.INITIALIZED, pathStatus.getType());
608 		assertEquals(commit, pathStatus.getHeadId());
609 		assertEquals(commit, pathStatus.getIndexId());
610 
611 		try (SubmoduleWalk walk = SubmoduleWalk
612 				.forIndex(git2.getRepository())) {
613 			assertTrue(walk.next());
614 			Repository clonedSub1 = walk.getRepository();
615 			addRepoToClose(clonedSub1);
616 			assertNotNull(clonedSub1);
617 			assertEquals(new File(git2.getRepository().getWorkTree(),
618 					walk.getPath()), clonedSub1.getWorkTree());
619 			assertEquals(
620 					new File(new File(git2.getRepository().getDirectory(),
621 							"modules"), walk.getPath()),
622 					clonedSub1.getDirectory());
623 		}
624 	}
625 
626 	@Test
627 	public void testCloneRepositoryWithNestedSubmodules() throws Exception {
628 		git.checkout().setName(Constants.MASTER).call();
629 
630 		// Create submodule 1
631 		File submodule1 = createTempDirectory("testCloneRepositoryWithNestedSubmodules1");
632 		Git sub1Git = Git.init().setDirectory(submodule1).call();
633 		assertNotNull(sub1Git);
634 		Repository sub1 = sub1Git.getRepository();
635 		assertNotNull(sub1);
636 		addRepoToClose(sub1);
637 
638 		String file = "file.txt";
639 		String path = "sub";
640 
641 		write(new File(sub1.getWorkTree(), file), "content");
642 		sub1Git.add().addFilepattern(file).call();
643 		RevCommit commit = sub1Git.commit().setMessage("create file").call();
644 		assertNotNull(commit);
645 
646 		// Create submodule 2
647 		File submodule2 = createTempDirectory("testCloneRepositoryWithNestedSubmodules2");
648 		Git sub2Git = Git.init().setDirectory(submodule2).call();
649 		assertNotNull(sub2Git);
650 		Repository sub2 = sub2Git.getRepository();
651 		assertNotNull(sub2);
652 		addRepoToClose(sub2);
653 
654 		write(new File(sub2.getWorkTree(), file), "content");
655 		sub2Git.add().addFilepattern(file).call();
656 		RevCommit sub2Head = sub2Git.commit().setMessage("create file").call();
657 		assertNotNull(sub2Head);
658 
659 		// Add submodule 2 to submodule 1
660 		Repository r = sub1Git.submoduleAdd().setPath(path)
661 				.setURI(sub2.getDirectory().toURI().toString()).call();
662 		assertNotNull(r);
663 		addRepoToClose(r);
664 		RevCommit sub1Head = sub1Git.commit().setAll(true)
665 				.setMessage("Adding submodule").call();
666 		assertNotNull(sub1Head);
667 
668 		// Add submodule 1 to default repository
669 		r = git.submoduleAdd().setPath(path)
670 				.setURI(sub1.getDirectory().toURI().toString()).call();
671 		assertNotNull(r);
672 		addRepoToClose(r);
673 		assertNotNull(git.commit().setAll(true).setMessage("Adding submodule")
674 				.call());
675 
676 		// Clone default repository and include submodules
677 		File directory = createTempDirectory("testCloneRepositoryWithNestedSubmodules");
678 		CloneCommand clone = Git.cloneRepository();
679 		clone.setDirectory(directory);
680 		clone.setCloneSubmodules(true);
681 		clone.setURI(git.getRepository().getDirectory().toURI().toString());
682 		Git git2 = clone.call();
683 		addRepoToClose(git2.getRepository());
684 		assertNotNull(git2);
685 
686 		assertEquals(Constants.MASTER, git2.getRepository().getBranch());
687 		assertTrue(new File(git2.getRepository().getWorkTree(), path
688 				+ File.separatorChar + file).exists());
689 		assertTrue(new File(git2.getRepository().getWorkTree(), path
690 				+ File.separatorChar + path + File.separatorChar + file)
691 				.exists());
692 
693 		SubmoduleStatusCommand status = new SubmoduleStatusCommand(
694 				git2.getRepository());
695 		Map<String, SubmoduleStatus> statuses = status.call();
696 		SubmoduleStatus pathStatus = statuses.get(path);
697 		assertNotNull(pathStatus);
698 		assertEquals(SubmoduleStatusType.INITIALIZED, pathStatus.getType());
699 		assertEquals(sub1Head, pathStatus.getHeadId());
700 		assertEquals(sub1Head, pathStatus.getIndexId());
701 
702 		try (SubmoduleWalk walk = SubmoduleWalk
703 				.forIndex(git2.getRepository())) {
704 			assertTrue(walk.next());
705 			try (Repository clonedSub1 = walk.getRepository()) {
706 				assertNotNull(clonedSub1);
707 				assertEquals(new File(git2.getRepository().getWorkTree(),
708 						walk.getPath()), clonedSub1.getWorkTree());
709 				assertEquals(
710 						new File(new File(git2.getRepository().getDirectory(),
711 								"modules"), walk.getPath()),
712 						clonedSub1.getDirectory());
713 				status = new SubmoduleStatusCommand(clonedSub1);
714 				statuses = status.call();
715 			}
716 			assertFalse(walk.next());
717 		}
718 		pathStatus = statuses.get(path);
719 		assertNotNull(pathStatus);
720 		assertEquals(SubmoduleStatusType.INITIALIZED, pathStatus.getType());
721 		assertEquals(sub2Head, pathStatus.getHeadId());
722 		assertEquals(sub2Head, pathStatus.getIndexId());
723 	}
724 
725 	@Test
726 	public void testCloneWithAutoSetupRebase() throws Exception {
727 		File directory = createTempDirectory("testCloneRepository1");
728 		CloneCommand command = Git.cloneRepository();
729 		command.setDirectory(directory);
730 		command.setURI(fileUri());
731 		Git git2 = command.call();
732 		addRepoToClose(git2.getRepository());
733 		assertNull(git2.getRepository().getConfig().getEnum(
734 				BranchRebaseMode.values(),
735 				ConfigConstants.CONFIG_BRANCH_SECTION, "test",
736 				ConfigConstants.CONFIG_KEY_REBASE, null));
737 
738 		StoredConfig userConfig = SystemReader.getInstance()
739 				.getUserConfig();
740 		userConfig.setString(ConfigConstants.CONFIG_BRANCH_SECTION, null,
741 				ConfigConstants.CONFIG_KEY_AUTOSETUPREBASE,
742 				ConfigConstants.CONFIG_KEY_ALWAYS);
743 		userConfig.save();
744 		directory = createTempDirectory("testCloneRepository2");
745 		command = Git.cloneRepository();
746 		command.setDirectory(directory);
747 		command.setURI(fileUri());
748 		git2 = command.call();
749 		addRepoToClose(git2.getRepository());
750 		assertEquals(BranchRebaseMode.REBASE,
751 				git2.getRepository().getConfig().getEnum(
752 						BranchRebaseMode.values(),
753 						ConfigConstants.CONFIG_BRANCH_SECTION, "test",
754 						ConfigConstants.CONFIG_KEY_REBASE,
755 						BranchRebaseMode.NONE));
756 
757 		userConfig.setString(ConfigConstants.CONFIG_BRANCH_SECTION, null,
758 				ConfigConstants.CONFIG_KEY_AUTOSETUPREBASE,
759 				ConfigConstants.CONFIG_KEY_REMOTE);
760 		userConfig.save();
761 		directory = createTempDirectory("testCloneRepository2");
762 		command = Git.cloneRepository();
763 		command.setDirectory(directory);
764 		command.setURI(fileUri());
765 		git2 = command.call();
766 		addRepoToClose(git2.getRepository());
767 		assertEquals(BranchRebaseMode.REBASE,
768 				git2.getRepository().getConfig().getEnum(
769 						BranchRebaseMode.values(),
770 						ConfigConstants.CONFIG_BRANCH_SECTION, "test",
771 						ConfigConstants.CONFIG_KEY_REBASE,
772 						BranchRebaseMode.NONE));
773 
774 	}
775 
776 	@Test
777 	public void testCloneWithPullMerge() throws Exception {
778 		File directory = createTempDirectory("testCloneRepository1");
779 		try (Git g = Git.init().setDirectory(directory).setBare(false).call()) {
780 			g.remoteAdd().setName(Constants.DEFAULT_REMOTE_NAME)
781 					.setUri(new URIish(fileUri())).call();
782 			PullResult result = g.pull().setRebase(false).call();
783 			assertTrue(result.isSuccessful());
784 			assertEquals("refs/heads/master",
785 					g.getRepository().getFullBranch());
786 			checkFile(new File(directory, "Test.txt"), "Hello world");
787 		}
788 	}
789 
790 	@Test
791 	public void testCloneWithPullRebase() throws Exception {
792 		File directory = createTempDirectory("testCloneRepository1");
793 		try (Git g = Git.init().setDirectory(directory).setBare(false).call()) {
794 			g.remoteAdd().setName(Constants.DEFAULT_REMOTE_NAME)
795 					.setUri(new URIish(fileUri())).call();
796 			PullResult result = g.pull().setRebase(true).call();
797 			assertTrue(result.isSuccessful());
798 			assertEquals("refs/heads/master",
799 					g.getRepository().getFullBranch());
800 			checkFile(new File(directory, "Test.txt"), "Hello world");
801 		}
802 	}
803 
804 	private String fileUri() {
805 		return "file://" + git.getRepository().getWorkTree().getAbsolutePath();
806 	}
807 }