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