You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CloneCommandTest.java 27KB

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