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