Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367
  1. /*
  2. * Copyright (C) 2014, Google Inc.
  3. * and other copyright owners as documented in the project's IP log.
  4. *
  5. * This program and the accompanying materials are made available
  6. * under the terms of the Eclipse Distribution License v1.0 which
  7. * accompanies this distribution, is reproduced below, and is
  8. * available at http://www.eclipse.org/org/documents/edl-v10.php
  9. *
  10. * All rights reserved.
  11. *
  12. * Redistribution and use in source and binary forms, with or
  13. * without modification, are permitted provided that the following
  14. * conditions are met:
  15. *
  16. * - Redistributions of source code must retain the above copyright
  17. * notice, this list of conditions and the following disclaimer.
  18. *
  19. * - Redistributions in binary form must reproduce the above
  20. * copyright notice, this list of conditions and the following
  21. * disclaimer in the documentation and/or other materials provided
  22. * with the distribution.
  23. *
  24. * - Neither the name of the Eclipse Foundation, Inc. nor the
  25. * names of its contributors may be used to endorse or promote
  26. * products derived from this software without specific prior
  27. * written permission.
  28. *
  29. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  30. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  31. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  32. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  34. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  35. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  36. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  38. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  40. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  41. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42. */
  43. package org.eclipse.jgit.gitrepo;
  44. import static java.nio.charset.StandardCharsets.UTF_8;
  45. import static org.junit.Assert.assertEquals;
  46. import static org.junit.Assert.assertFalse;
  47. import static org.junit.Assert.assertNull;
  48. import static org.junit.Assert.assertTrue;
  49. import static org.junit.Assert.fail;
  50. import java.io.BufferedReader;
  51. import java.io.ByteArrayInputStream;
  52. import java.io.File;
  53. import java.io.IOException;
  54. import java.net.URI;
  55. import java.nio.file.Files;
  56. import java.nio.file.Path;
  57. import java.text.MessageFormat;
  58. import java.util.HashMap;
  59. import java.util.Map;
  60. import org.eclipse.jgit.api.Git;
  61. import org.eclipse.jgit.api.errors.GitAPIException;
  62. import org.eclipse.jgit.api.errors.InvalidRefNameException;
  63. import org.eclipse.jgit.api.errors.InvalidRemoteException;
  64. import org.eclipse.jgit.gitrepo.RepoCommand.RemoteFile;
  65. import org.eclipse.jgit.internal.JGitText;
  66. import org.eclipse.jgit.junit.JGitTestUtil;
  67. import org.eclipse.jgit.junit.RepositoryTestCase;
  68. import org.eclipse.jgit.lib.BlobBasedConfig;
  69. import org.eclipse.jgit.lib.Config;
  70. import org.eclipse.jgit.lib.Constants;
  71. import org.eclipse.jgit.lib.ObjectId;
  72. import org.eclipse.jgit.lib.ObjectReader;
  73. import org.eclipse.jgit.lib.Ref;
  74. import org.eclipse.jgit.lib.Repository;
  75. import org.eclipse.jgit.revwalk.RevCommit;
  76. import org.eclipse.jgit.storage.file.FileBasedConfig;
  77. import org.eclipse.jgit.treewalk.TreeWalk;
  78. import org.eclipse.jgit.util.FS;
  79. import org.junit.Test;
  80. public class RepoCommandTest extends RepositoryTestCase {
  81. private static final String BRANCH = "branch";
  82. private static final String TAG = "release";
  83. private Repository defaultDb;
  84. private Repository notDefaultDb;
  85. private Repository groupADb;
  86. private Repository groupBDb;
  87. private String rootUri;
  88. private String defaultUri;
  89. private String notDefaultUri;
  90. private String groupAUri;
  91. private String groupBUri;
  92. private ObjectId oldCommitId;
  93. @Override
  94. public void setUp() throws Exception {
  95. super.setUp();
  96. defaultDb = createWorkRepository();
  97. try (Git git = new Git(defaultDb)) {
  98. JGitTestUtil.writeTrashFile(defaultDb, "hello.txt", "branch world");
  99. git.add().addFilepattern("hello.txt").call();
  100. oldCommitId = git.commit().setMessage("Initial commit").call().getId();
  101. git.checkout().setName(BRANCH).setCreateBranch(true).call();
  102. git.checkout().setName("master").call();
  103. git.tag().setName(TAG).call();
  104. JGitTestUtil.writeTrashFile(defaultDb, "hello.txt", "master world");
  105. git.add().addFilepattern("hello.txt").call();
  106. git.commit().setMessage("Second commit").call();
  107. addRepoToClose(defaultDb);
  108. }
  109. notDefaultDb = createWorkRepository();
  110. try (Git git = new Git(notDefaultDb)) {
  111. JGitTestUtil.writeTrashFile(notDefaultDb, "world.txt", "hello");
  112. git.add().addFilepattern("world.txt").call();
  113. git.commit().setMessage("Initial commit").call();
  114. addRepoToClose(notDefaultDb);
  115. }
  116. groupADb = createWorkRepository();
  117. try (Git git = new Git(groupADb)) {
  118. JGitTestUtil.writeTrashFile(groupADb, "a.txt", "world");
  119. git.add().addFilepattern("a.txt").call();
  120. git.commit().setMessage("Initial commit").call();
  121. addRepoToClose(groupADb);
  122. }
  123. groupBDb = createWorkRepository();
  124. try (Git git = new Git(groupBDb)) {
  125. JGitTestUtil.writeTrashFile(groupBDb, "b.txt", "world");
  126. git.add().addFilepattern("b.txt").call();
  127. git.commit().setMessage("Initial commit").call();
  128. addRepoToClose(groupBDb);
  129. }
  130. resolveRelativeUris();
  131. }
  132. static class IndexedRepos implements RepoCommand.RemoteReader {
  133. Map<String, Repository> uriRepoMap;
  134. IndexedRepos() {
  135. uriRepoMap = new HashMap<>();
  136. }
  137. void put(String u, Repository r) {
  138. uriRepoMap.put(u, r);
  139. }
  140. @Override
  141. public ObjectId sha1(String uri, String refname) throws GitAPIException {
  142. if (!uriRepoMap.containsKey(uri)) {
  143. return null;
  144. }
  145. Repository r = uriRepoMap.get(uri);
  146. try {
  147. Ref ref = r.findRef(refname);
  148. if (ref == null) return null;
  149. ref = r.getRefDatabase().peel(ref);
  150. ObjectId id = ref.getObjectId();
  151. return id;
  152. } catch (IOException e) {
  153. throw new InvalidRemoteException("", e);
  154. }
  155. }
  156. @Override
  157. public RemoteFile readFileWithMode(String uri, String ref, String path)
  158. throws GitAPIException, IOException {
  159. Repository repo = uriRepoMap.get(uri);
  160. ObjectId refCommitId = sha1(uri, ref);
  161. if (refCommitId == null) {
  162. throw new InvalidRefNameException(MessageFormat
  163. .format(JGitText.get().refNotResolved, ref));
  164. }
  165. RevCommit commit = repo.parseCommit(refCommitId);
  166. TreeWalk tw = TreeWalk.forPath(repo, path, commit.getTree());
  167. // TODO(ifrade): Cope better with big files (e.g. using InputStream
  168. // instead of byte[])
  169. return new RemoteFile(tw.getObjectReader().open(tw.getObjectId(0))
  170. .getCachedBytes(Integer.MAX_VALUE), tw.getFileMode(0));
  171. }
  172. }
  173. private Repository cloneRepository(Repository repo, boolean bare)
  174. throws Exception {
  175. Repository r = Git.cloneRepository()
  176. .setURI(repo.getDirectory().toURI().toString())
  177. .setDirectory(createUniqueTestGitDir(true)).setBare(bare).call()
  178. .getRepository();
  179. if (bare) {
  180. assertTrue(r.isBare());
  181. } else {
  182. assertFalse(r.isBare());
  183. }
  184. return r;
  185. }
  186. private static void assertContents(Path path, String expected)
  187. throws IOException {
  188. try (BufferedReader reader = Files.newBufferedReader(path, UTF_8)) {
  189. String content = reader.readLine();
  190. assertEquals("Unexpected content in " + path.getFileName(),
  191. expected, content);
  192. }
  193. }
  194. @Test
  195. public void runTwiceIsNOP() throws Exception {
  196. try (Repository child = cloneRepository(groupADb, true);
  197. Repository dest = cloneRepository(db, true)) {
  198. StringBuilder xmlContent = new StringBuilder();
  199. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  200. .append("<manifest>")
  201. .append("<remote name=\"remote1\" fetch=\"..\" />")
  202. .append("<default revision=\"master\" remote=\"remote1\" />")
  203. .append("<project path=\"base\" name=\"platform/base\" />")
  204. .append("</manifest>");
  205. RepoCommand cmd = new RepoCommand(dest);
  206. IndexedRepos repos = new IndexedRepos();
  207. repos.put("platform/base", child);
  208. RevCommit commit = cmd
  209. .setInputStream(new ByteArrayInputStream(
  210. xmlContent.toString().getBytes(UTF_8)))
  211. .setRemoteReader(repos).setURI("platform/")
  212. .setTargetURI("platform/superproject")
  213. .setRecordRemoteBranch(true).setRecordSubmoduleLabels(true)
  214. .call();
  215. String firstIdStr = commit.getId().name() + ":" + ".gitmodules";
  216. commit = new RepoCommand(dest)
  217. .setInputStream(new ByteArrayInputStream(
  218. xmlContent.toString().getBytes(UTF_8)))
  219. .setRemoteReader(repos).setURI("platform/")
  220. .setTargetURI("platform/superproject")
  221. .setRecordRemoteBranch(true).setRecordSubmoduleLabels(true)
  222. .call();
  223. String idStr = commit.getId().name() + ":" + ".gitmodules";
  224. assertEquals(firstIdStr, idStr);
  225. }
  226. }
  227. @Test
  228. public void androidSetup() throws Exception {
  229. try (Repository child = cloneRepository(groupADb, true);
  230. Repository dest = cloneRepository(db, true)) {
  231. StringBuilder xmlContent = new StringBuilder();
  232. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  233. .append("<manifest>")
  234. .append("<remote name=\"remote1\" fetch=\"..\" />")
  235. .append("<default revision=\"master\" remote=\"remote1\" />")
  236. .append("<project path=\"base\" name=\"platform/base\" />")
  237. .append("</manifest>");
  238. RepoCommand cmd = new RepoCommand(dest);
  239. IndexedRepos repos = new IndexedRepos();
  240. repos.put("platform/base", child);
  241. RevCommit commit = cmd
  242. .setInputStream(new ByteArrayInputStream(
  243. xmlContent.toString().getBytes(UTF_8)))
  244. .setRemoteReader(repos).setURI("platform/")
  245. .setTargetURI("platform/superproject")
  246. .setRecordRemoteBranch(true).setRecordSubmoduleLabels(true)
  247. .call();
  248. String idStr = commit.getId().name() + ":" + ".gitmodules";
  249. ObjectId modId = dest.resolve(idStr);
  250. try (ObjectReader reader = dest.newObjectReader()) {
  251. byte[] bytes = reader.open(modId)
  252. .getCachedBytes(Integer.MAX_VALUE);
  253. Config base = new Config();
  254. BlobBasedConfig cfg = new BlobBasedConfig(base, bytes);
  255. String subUrl = cfg.getString("submodule", "platform/base",
  256. "url");
  257. assertEquals(subUrl, "../base");
  258. }
  259. }
  260. }
  261. @Test
  262. public void recordUnreachableRemotes() throws Exception {
  263. StringBuilder xmlContent = new StringBuilder();
  264. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  265. .append("<manifest>")
  266. .append("<remote name=\"remote1\" fetch=\"https://host.com/\" />")
  267. .append("<default revision=\"master\" remote=\"remote1\" />")
  268. .append("<project path=\"base\" name=\"platform/base\" />")
  269. .append("</manifest>");
  270. try (Repository dest = cloneRepository(db, true)) {
  271. RevCommit commit = new RepoCommand(dest)
  272. .setInputStream(new ByteArrayInputStream(
  273. xmlContent.toString().getBytes(UTF_8)))
  274. .setRemoteReader(new IndexedRepos()).setURI("platform/")
  275. .setTargetURI("platform/superproject")
  276. .setRecordRemoteBranch(true).setIgnoreRemoteFailures(true)
  277. .setRecordSubmoduleLabels(true).call();
  278. String idStr = commit.getId().name() + ":" + ".gitmodules";
  279. ObjectId modId = dest.resolve(idStr);
  280. try (ObjectReader reader = dest.newObjectReader()) {
  281. byte[] bytes = reader.open(modId)
  282. .getCachedBytes(Integer.MAX_VALUE);
  283. Config base = new Config();
  284. BlobBasedConfig cfg = new BlobBasedConfig(base, bytes);
  285. String subUrl = cfg.getString("submodule", "platform/base",
  286. "url");
  287. assertEquals(subUrl, "https://host.com/platform/base");
  288. }
  289. }
  290. }
  291. @Test
  292. public void gerritSetup() throws Exception {
  293. try (Repository child = cloneRepository(groupADb, true);
  294. Repository dest = cloneRepository(db, true)) {
  295. StringBuilder xmlContent = new StringBuilder();
  296. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  297. .append("<manifest>")
  298. .append("<remote name=\"remote1\" fetch=\".\" />")
  299. .append("<default revision=\"master\" remote=\"remote1\" />")
  300. .append("<project path=\"plugins/cookbook\" name=\"plugins/cookbook\" />")
  301. .append("</manifest>");
  302. RepoCommand cmd = new RepoCommand(dest);
  303. IndexedRepos repos = new IndexedRepos();
  304. repos.put("plugins/cookbook", child);
  305. RevCommit commit = cmd
  306. .setInputStream(new ByteArrayInputStream(
  307. xmlContent.toString().getBytes(UTF_8)))
  308. .setRemoteReader(repos).setURI("").setTargetURI("gerrit")
  309. .setRecordRemoteBranch(true).setRecordSubmoduleLabels(true)
  310. .call();
  311. String idStr = commit.getId().name() + ":" + ".gitmodules";
  312. ObjectId modId = dest.resolve(idStr);
  313. try (ObjectReader reader = dest.newObjectReader()) {
  314. byte[] bytes = reader.open(modId)
  315. .getCachedBytes(Integer.MAX_VALUE);
  316. Config base = new Config();
  317. BlobBasedConfig cfg = new BlobBasedConfig(base, bytes);
  318. String subUrl = cfg.getString("submodule", "plugins/cookbook",
  319. "url");
  320. assertEquals(subUrl, "../plugins/cookbook");
  321. }
  322. }
  323. }
  324. @Test
  325. public void absoluteRemoteURL() throws Exception {
  326. try (Repository child = cloneRepository(groupADb, true);
  327. Repository dest = cloneRepository(db, true)) {
  328. String abs = "https://chromium.googlesource.com";
  329. String repoUrl = "https://chromium.googlesource.com/chromium/src";
  330. boolean fetchSlash = false;
  331. boolean baseSlash = false;
  332. do {
  333. do {
  334. String fetchUrl = fetchSlash ? abs + "/" : abs;
  335. String baseUrl = baseSlash ? abs + "/" : abs;
  336. StringBuilder xmlContent = new StringBuilder();
  337. xmlContent.append(
  338. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  339. .append("<manifest>")
  340. .append("<remote name=\"origin\" fetch=\""
  341. + fetchUrl + "\" />")
  342. .append("<default revision=\"master\" remote=\"origin\" />")
  343. .append("<project path=\"src\" name=\"chromium/src\" />")
  344. .append("</manifest>");
  345. RepoCommand cmd = new RepoCommand(dest);
  346. IndexedRepos repos = new IndexedRepos();
  347. repos.put(repoUrl, child);
  348. RevCommit commit = cmd
  349. .setInputStream(new ByteArrayInputStream(
  350. xmlContent.toString().getBytes(UTF_8)))
  351. .setRemoteReader(repos).setURI(baseUrl)
  352. .setTargetURI("gerrit").setRecordRemoteBranch(true)
  353. .setRecordSubmoduleLabels(true).call();
  354. String idStr = commit.getId().name() + ":" + ".gitmodules";
  355. ObjectId modId = dest.resolve(idStr);
  356. try (ObjectReader reader = dest.newObjectReader()) {
  357. byte[] bytes = reader.open(modId)
  358. .getCachedBytes(Integer.MAX_VALUE);
  359. Config base = new Config();
  360. BlobBasedConfig cfg = new BlobBasedConfig(base, bytes);
  361. String subUrl = cfg.getString("submodule",
  362. "chromium/src", "url");
  363. assertEquals(
  364. "https://chromium.googlesource.com/chromium/src",
  365. subUrl);
  366. }
  367. fetchSlash = !fetchSlash;
  368. } while (fetchSlash);
  369. baseSlash = !baseSlash;
  370. } while (baseSlash);
  371. }
  372. }
  373. @Test
  374. public void absoluteRemoteURLAbsoluteTargetURL() throws Exception {
  375. try (Repository child = cloneRepository(groupADb, true);
  376. Repository dest = cloneRepository(db, true)) {
  377. String abs = "https://chromium.googlesource.com";
  378. String repoUrl = "https://chromium.googlesource.com/chromium/src";
  379. boolean fetchSlash = false;
  380. boolean baseSlash = false;
  381. do {
  382. do {
  383. String fetchUrl = fetchSlash ? abs + "/" : abs;
  384. String baseUrl = baseSlash ? abs + "/" : abs;
  385. StringBuilder xmlContent = new StringBuilder();
  386. xmlContent.append(
  387. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  388. .append("<manifest>")
  389. .append("<remote name=\"origin\" fetch=\""
  390. + fetchUrl + "\" />")
  391. .append("<default revision=\"master\" remote=\"origin\" />")
  392. .append("<project path=\"src\" name=\"chromium/src\" />")
  393. .append("</manifest>");
  394. RepoCommand cmd = new RepoCommand(dest);
  395. IndexedRepos repos = new IndexedRepos();
  396. repos.put(repoUrl, child);
  397. RevCommit commit = cmd
  398. .setInputStream(new ByteArrayInputStream(
  399. xmlContent.toString().getBytes(UTF_8)))
  400. .setRemoteReader(repos).setURI(baseUrl)
  401. .setTargetURI(abs + "/superproject")
  402. .setRecordRemoteBranch(true)
  403. .setRecordSubmoduleLabels(true).call();
  404. String idStr = commit.getId().name() + ":" + ".gitmodules";
  405. ObjectId modId = dest.resolve(idStr);
  406. try (ObjectReader reader = dest.newObjectReader()) {
  407. byte[] bytes = reader.open(modId)
  408. .getCachedBytes(Integer.MAX_VALUE);
  409. Config base = new Config();
  410. BlobBasedConfig cfg = new BlobBasedConfig(base, bytes);
  411. String subUrl = cfg.getString("submodule",
  412. "chromium/src", "url");
  413. assertEquals("../chromium/src", subUrl);
  414. }
  415. fetchSlash = !fetchSlash;
  416. } while (fetchSlash);
  417. baseSlash = !baseSlash;
  418. } while (baseSlash);
  419. }
  420. }
  421. @Test
  422. public void testAddRepoManifest() throws Exception {
  423. StringBuilder xmlContent = new StringBuilder();
  424. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  425. .append("<manifest>")
  426. .append("<remote name=\"remote1\" fetch=\".\" />")
  427. .append("<default revision=\"master\" remote=\"remote1\" />")
  428. .append("<project path=\"foo\" name=\"")
  429. .append(defaultUri)
  430. .append("\" />")
  431. .append("</manifest>");
  432. writeTrashFile("manifest.xml", xmlContent.toString());
  433. RepoCommand command = new RepoCommand(db);
  434. command.setPath(db.getWorkTree().getAbsolutePath() + "/manifest.xml")
  435. .setURI(rootUri)
  436. .call();
  437. File hello = new File(db.getWorkTree(), "foo/hello.txt");
  438. assertTrue("submodule should be checked out", hello.exists());
  439. assertContents(hello.toPath(), "master world");
  440. }
  441. @Test
  442. public void testRepoManifestGroups() throws Exception {
  443. StringBuilder xmlContent = new StringBuilder();
  444. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  445. .append("<manifest>")
  446. .append("<remote name=\"remote1\" fetch=\".\" />")
  447. .append("<default revision=\"master\" remote=\"remote1\" />")
  448. .append("<project path=\"foo\" name=\"")
  449. .append(defaultUri)
  450. .append("\" groups=\"a,test\" />")
  451. .append("<project path=\"bar\" name=\"")
  452. .append(notDefaultUri)
  453. .append("\" groups=\"notdefault\" />")
  454. .append("<project path=\"a\" name=\"")
  455. .append(groupAUri)
  456. .append("\" groups=\"a\" />")
  457. .append("<project path=\"b\" name=\"")
  458. .append(groupBUri)
  459. .append("\" groups=\"b\" />")
  460. .append("</manifest>");
  461. // default should have foo, a & b
  462. Repository localDb = createWorkRepository();
  463. JGitTestUtil.writeTrashFile(
  464. localDb, "manifest.xml", xmlContent.toString());
  465. RepoCommand command = new RepoCommand(localDb);
  466. command
  467. .setPath(localDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
  468. .setURI(rootUri)
  469. .call();
  470. File file = new File(localDb.getWorkTree(), "foo/hello.txt");
  471. assertTrue("default should have foo", file.exists());
  472. file = new File(localDb.getWorkTree(), "bar/world.txt");
  473. assertFalse("default shouldn't have bar", file.exists());
  474. file = new File(localDb.getWorkTree(), "a/a.txt");
  475. assertTrue("default should have a", file.exists());
  476. file = new File(localDb.getWorkTree(), "b/b.txt");
  477. assertTrue("default should have b", file.exists());
  478. // all,-a should have bar & b
  479. localDb = createWorkRepository();
  480. JGitTestUtil.writeTrashFile(
  481. localDb, "manifest.xml", xmlContent.toString());
  482. command = new RepoCommand(localDb);
  483. command
  484. .setPath(localDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
  485. .setURI(rootUri)
  486. .setGroups("all,-a")
  487. .call();
  488. file = new File(localDb.getWorkTree(), "foo/hello.txt");
  489. assertFalse("\"all,-a\" shouldn't have foo", file.exists());
  490. file = new File(localDb.getWorkTree(), "bar/world.txt");
  491. assertTrue("\"all,-a\" should have bar", file.exists());
  492. file = new File(localDb.getWorkTree(), "a/a.txt");
  493. assertFalse("\"all,-a\" shuoldn't have a", file.exists());
  494. file = new File(localDb.getWorkTree(), "b/b.txt");
  495. assertTrue("\"all,-a\" should have b", file.exists());
  496. }
  497. @Test
  498. public void testRepoManifestCopyFile() throws Exception {
  499. Repository localDb = createWorkRepository();
  500. StringBuilder xmlContent = new StringBuilder();
  501. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  502. .append("<manifest>")
  503. .append("<remote name=\"remote1\" fetch=\".\" />")
  504. .append("<default revision=\"master\" remote=\"remote1\" />")
  505. .append("<project path=\"foo\" name=\"")
  506. .append(defaultUri)
  507. .append("\">")
  508. .append("<copyfile src=\"hello.txt\" dest=\"Hello\" />")
  509. .append("</project>")
  510. .append("</manifest>");
  511. JGitTestUtil.writeTrashFile(
  512. localDb, "manifest.xml", xmlContent.toString());
  513. RepoCommand command = new RepoCommand(localDb);
  514. command
  515. .setPath(localDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
  516. .setURI(rootUri)
  517. .call();
  518. // The original file should exist
  519. File hello = new File(localDb.getWorkTree(), "foo/hello.txt");
  520. assertTrue("The original file should exist", hello.exists());
  521. assertFalse("The original file should not be executable",
  522. hello.canExecute());
  523. assertContents(hello.toPath(), "master world");
  524. // The dest file should also exist
  525. hello = new File(localDb.getWorkTree(), "Hello");
  526. assertTrue("The destination file should exist", hello.exists());
  527. assertFalse("The destination file should not be executable",
  528. hello.canExecute());
  529. assertContents(hello.toPath(), "master world");
  530. }
  531. @Test
  532. public void testRepoManifestCopyFile_executable() throws Exception {
  533. try (Git git = new Git(defaultDb)) {
  534. git.checkout().setName("master").call();
  535. File f = JGitTestUtil.writeTrashFile(defaultDb, "hello.sh",
  536. "content of the executable file");
  537. f.setExecutable(true);
  538. git.add().addFilepattern("hello.sh").call();
  539. git.commit().setMessage("Add binary file").call();
  540. }
  541. Repository localDb = createWorkRepository();
  542. StringBuilder xmlContent = new StringBuilder();
  543. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  544. .append("<manifest>")
  545. .append("<remote name=\"remote1\" fetch=\".\" />")
  546. .append("<default revision=\"master\" remote=\"remote1\" />")
  547. .append("<project path=\"foo\" name=\"").append(defaultUri)
  548. .append("\">")
  549. .append("<copyfile src=\"hello.sh\" dest=\"copy-hello.sh\" />")
  550. .append("</project>").append("</manifest>");
  551. JGitTestUtil.writeTrashFile(localDb, "manifest.xml",
  552. xmlContent.toString());
  553. RepoCommand command = new RepoCommand(localDb);
  554. command.setPath(
  555. localDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
  556. .setURI(rootUri).call();
  557. // The original file should exist and be an executable
  558. File hello = new File(localDb.getWorkTree(), "foo/hello.sh");
  559. assertTrue("The original file should exist", hello.exists());
  560. assertTrue("The original file must be executable", hello.canExecute());
  561. try (BufferedReader reader = Files.newBufferedReader(hello.toPath(),
  562. UTF_8)) {
  563. String content = reader.readLine();
  564. assertEquals("The original file should have expected content",
  565. "content of the executable file", content);
  566. }
  567. // The destination file should also exist and be an executable
  568. hello = new File(localDb.getWorkTree(), "copy-hello.sh");
  569. assertTrue("The destination file should exist", hello.exists());
  570. assertTrue("The destination file must be executable",
  571. hello.canExecute());
  572. try (BufferedReader reader = Files.newBufferedReader(hello.toPath(),
  573. UTF_8)) {
  574. String content = reader.readLine();
  575. assertEquals("The destination file should have expected content",
  576. "content of the executable file", content);
  577. }
  578. }
  579. @Test
  580. public void testBareRepo() throws Exception {
  581. Repository remoteDb = createBareRepository();
  582. Repository tempDb = createWorkRepository();
  583. StringBuilder xmlContent = new StringBuilder();
  584. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  585. .append("<manifest>")
  586. .append("<remote name=\"remote1\" fetch=\".\" />")
  587. .append("<default revision=\"master\" remote=\"remote1\" />")
  588. .append("<project path=\"foo\" name=\"").append(defaultUri)
  589. .append("\" />").append("</manifest>");
  590. JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
  591. xmlContent.toString());
  592. RepoCommand command = new RepoCommand(remoteDb);
  593. command.setPath(
  594. tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
  595. .setURI(rootUri).call();
  596. // Clone it
  597. File directory = createTempDirectory("testBareRepo");
  598. try (Repository localDb = Git.cloneRepository().setDirectory(directory)
  599. .setURI(remoteDb.getDirectory().toURI().toString()).call()
  600. .getRepository()) {
  601. // The .gitmodules file should exist
  602. File gitmodules = new File(localDb.getWorkTree(), ".gitmodules");
  603. assertTrue("The .gitmodules file should exist",
  604. gitmodules.exists());
  605. // The first line of .gitmodules file should be expected
  606. try (BufferedReader reader = Files
  607. .newBufferedReader(gitmodules.toPath(), UTF_8)) {
  608. String content = reader.readLine();
  609. assertEquals(
  610. "The first line of .gitmodules file should be as expected",
  611. "[submodule \"" + defaultUri + "\"]", content);
  612. }
  613. // The gitlink should be the same as remote head sha1
  614. String gitlink = localDb.resolve(Constants.HEAD + ":foo").name();
  615. String remote = defaultDb.resolve(Constants.HEAD).name();
  616. assertEquals("The gitlink should be the same as remote head",
  617. remote, gitlink);
  618. }
  619. }
  620. @Test
  621. public void testRevision() throws Exception {
  622. StringBuilder xmlContent = new StringBuilder();
  623. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  624. .append("<manifest>")
  625. .append("<remote name=\"remote1\" fetch=\".\" />")
  626. .append("<default revision=\"master\" remote=\"remote1\" />")
  627. .append("<project path=\"foo\" name=\"")
  628. .append(defaultUri)
  629. .append("\" revision=\"")
  630. .append(oldCommitId.name())
  631. .append("\" />")
  632. .append("</manifest>");
  633. writeTrashFile("manifest.xml", xmlContent.toString());
  634. RepoCommand command = new RepoCommand(db);
  635. command.setPath(db.getWorkTree().getAbsolutePath() + "/manifest.xml")
  636. .setURI(rootUri)
  637. .call();
  638. File hello = new File(db.getWorkTree(), "foo/hello.txt");
  639. try (BufferedReader reader = Files.newBufferedReader(hello.toPath(),
  640. UTF_8)) {
  641. String content = reader.readLine();
  642. assertEquals("submodule content should be as expected",
  643. "branch world", content);
  644. }
  645. }
  646. @Test
  647. public void testRevisionBranch() throws Exception {
  648. StringBuilder xmlContent = new StringBuilder();
  649. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  650. .append("<manifest>")
  651. .append("<remote name=\"remote1\" fetch=\".\" />")
  652. .append("<default revision=\"")
  653. .append(BRANCH)
  654. .append("\" remote=\"remote1\" />")
  655. .append("<project path=\"foo\" name=\"")
  656. .append(defaultUri)
  657. .append("\" />")
  658. .append("</manifest>");
  659. writeTrashFile("manifest.xml", xmlContent.toString());
  660. RepoCommand command = new RepoCommand(db);
  661. command.setPath(db.getWorkTree().getAbsolutePath() + "/manifest.xml")
  662. .setURI(rootUri)
  663. .call();
  664. File hello = new File(db.getWorkTree(), "foo/hello.txt");
  665. assertContents(hello.toPath(), "branch world");
  666. }
  667. @Test
  668. public void testRevisionTag() throws Exception {
  669. StringBuilder xmlContent = new StringBuilder();
  670. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  671. .append("<manifest>")
  672. .append("<remote name=\"remote1\" fetch=\".\" />")
  673. .append("<default revision=\"master\" remote=\"remote1\" />")
  674. .append("<project path=\"foo\" name=\"")
  675. .append(defaultUri)
  676. .append("\" revision=\"")
  677. .append(TAG)
  678. .append("\" />")
  679. .append("</manifest>");
  680. writeTrashFile("manifest.xml", xmlContent.toString());
  681. RepoCommand command = new RepoCommand(db);
  682. command.setPath(db.getWorkTree().getAbsolutePath() + "/manifest.xml")
  683. .setURI(rootUri)
  684. .call();
  685. File hello = new File(db.getWorkTree(), "foo/hello.txt");
  686. assertContents(hello.toPath(), "branch world");
  687. }
  688. @Test
  689. public void testRevisionBare() throws Exception {
  690. Repository remoteDb = createBareRepository();
  691. Repository tempDb = createWorkRepository();
  692. StringBuilder xmlContent = new StringBuilder();
  693. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  694. .append("<manifest>")
  695. .append("<remote name=\"remote1\" fetch=\".\" />")
  696. .append("<default revision=\"").append(BRANCH)
  697. .append("\" remote=\"remote1\" />")
  698. .append("<project path=\"foo\" name=\"").append(defaultUri)
  699. .append("\" />").append("</manifest>");
  700. JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
  701. xmlContent.toString());
  702. RepoCommand command = new RepoCommand(remoteDb);
  703. command.setPath(
  704. tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
  705. .setURI(rootUri).call();
  706. // Clone it
  707. File directory = createTempDirectory("testRevisionBare");
  708. try (Repository localDb = Git.cloneRepository().setDirectory(directory)
  709. .setURI(remoteDb.getDirectory().toURI().toString()).call()
  710. .getRepository()) {
  711. // The gitlink should be the same as oldCommitId
  712. String gitlink = localDb.resolve(Constants.HEAD + ":foo").name();
  713. assertEquals("The gitlink is same as remote head",
  714. oldCommitId.name(), gitlink);
  715. }
  716. }
  717. @Test
  718. public void testCopyFileBare() throws Exception {
  719. Repository remoteDb = createBareRepository();
  720. Repository tempDb = createWorkRepository();
  721. StringBuilder xmlContent = new StringBuilder();
  722. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  723. .append("<manifest>")
  724. .append("<remote name=\"remote1\" fetch=\".\" />")
  725. .append("<default revision=\"master\" remote=\"remote1\" />")
  726. .append("<project path=\"foo\" name=\"").append(defaultUri)
  727. .append("\" revision=\"").append(BRANCH).append("\" >")
  728. .append("<copyfile src=\"hello.txt\" dest=\"Hello\" />")
  729. .append("<copyfile src=\"hello.txt\" dest=\"foo/Hello\" />")
  730. .append("</project>").append("</manifest>");
  731. JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
  732. xmlContent.toString());
  733. RepoCommand command = new RepoCommand(remoteDb);
  734. command.setPath(
  735. tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
  736. .setURI(rootUri).call();
  737. // Clone it
  738. File directory = createTempDirectory("testCopyFileBare");
  739. try (Repository localDb = Git.cloneRepository().setDirectory(directory)
  740. .setURI(remoteDb.getDirectory().toURI().toString()).call()
  741. .getRepository()) {
  742. // The Hello file should exist
  743. File hello = new File(localDb.getWorkTree(), "Hello");
  744. assertTrue("The Hello file should exist", hello.exists());
  745. // The foo/Hello file should be skipped.
  746. File foohello = new File(localDb.getWorkTree(), "foo/Hello");
  747. assertFalse("The foo/Hello file should be skipped",
  748. foohello.exists());
  749. // The content of Hello file should be expected
  750. assertContents(hello.toPath(), "branch world");
  751. }
  752. }
  753. @Test
  754. public void testCopyFileBare_executable() throws Exception {
  755. try (Git git = new Git(defaultDb)) {
  756. git.checkout().setName(BRANCH).call();
  757. File f = JGitTestUtil.writeTrashFile(defaultDb, "hello.sh",
  758. "content of the executable file");
  759. f.setExecutable(true);
  760. git.add().addFilepattern("hello.sh").call();
  761. git.commit().setMessage("Add binary file").call();
  762. }
  763. Repository remoteDb = createBareRepository();
  764. Repository tempDb = createWorkRepository();
  765. StringBuilder xmlContent = new StringBuilder();
  766. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  767. .append("<manifest>")
  768. .append("<remote name=\"remote1\" fetch=\".\" />")
  769. .append("<default revision=\"master\" remote=\"remote1\" />")
  770. .append("<project path=\"foo\" name=\"").append(defaultUri)
  771. .append("\" revision=\"").append(BRANCH)
  772. .append("\" >")
  773. .append("<copyfile src=\"hello.txt\" dest=\"Hello\" />")
  774. .append("<copyfile src=\"hello.txt\" dest=\"foo/Hello\" />")
  775. .append("<copyfile src=\"hello.sh\" dest=\"copy-hello.sh\" />")
  776. .append("</project>").append("</manifest>");
  777. JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
  778. xmlContent.toString());
  779. RepoCommand command = new RepoCommand(remoteDb);
  780. command.setPath(
  781. tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
  782. .setURI(rootUri).call();
  783. // Clone it
  784. File directory = createTempDirectory("testCopyFileBare");
  785. try (Repository localDb = Git.cloneRepository().setDirectory(directory)
  786. .setURI(remoteDb.getDirectory().toURI().toString()).call()
  787. .getRepository()) {
  788. // The Hello file should exist
  789. File hello = new File(localDb.getWorkTree(), "Hello");
  790. assertTrue("The Hello file should exist", hello.exists());
  791. // The foo/Hello file should be skipped.
  792. File foohello = new File(localDb.getWorkTree(), "foo/Hello");
  793. assertFalse("The foo/Hello file should be skipped",
  794. foohello.exists());
  795. // The content of Hello file should be expected
  796. try (BufferedReader reader = Files.newBufferedReader(hello.toPath(),
  797. UTF_8)) {
  798. String content = reader.readLine();
  799. assertEquals("The Hello file should have expected content",
  800. "branch world", content);
  801. }
  802. // The executable file must be there and preserve the executable bit
  803. File helloSh = new File(localDb.getWorkTree(), "copy-hello.sh");
  804. assertTrue("Destination file should exist", helloSh.exists());
  805. assertContents(helloSh.toPath(), "content of the executable file");
  806. assertTrue("Destination file should be executable",
  807. helloSh.canExecute());
  808. }
  809. }
  810. @Test
  811. public void testReplaceManifestBare() throws Exception {
  812. Repository remoteDb = createBareRepository();
  813. Repository tempDb = createWorkRepository();
  814. StringBuilder xmlContent = new StringBuilder();
  815. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  816. .append("<manifest>")
  817. .append("<remote name=\"remote1\" fetch=\".\" />")
  818. .append("<default revision=\"master\" remote=\"remote1\" />")
  819. .append("<project path=\"foo\" name=\"").append(defaultUri)
  820. .append("\" revision=\"").append(BRANCH).append("\" >")
  821. .append("<copyfile src=\"hello.txt\" dest=\"Hello\" />")
  822. .append("</project>").append("</manifest>");
  823. JGitTestUtil.writeTrashFile(tempDb, "old.xml", xmlContent.toString());
  824. RepoCommand command = new RepoCommand(remoteDb);
  825. command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/old.xml")
  826. .setURI(rootUri).call();
  827. xmlContent = new StringBuilder();
  828. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  829. .append("<manifest>")
  830. .append("<remote name=\"remote1\" fetch=\".\" />")
  831. .append("<default revision=\"master\" remote=\"remote1\" />")
  832. .append("<project path=\"bar\" name=\"").append(notDefaultUri)
  833. .append("\" >")
  834. .append("<copyfile src=\"world.txt\" dest=\"World.txt\" />")
  835. .append("</project>").append("</manifest>");
  836. JGitTestUtil.writeTrashFile(tempDb, "new.xml", xmlContent.toString());
  837. command = new RepoCommand(remoteDb);
  838. command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/new.xml")
  839. .setURI(rootUri).call();
  840. // Clone it
  841. File directory = createTempDirectory("testReplaceManifestBare");
  842. File dotmodules;
  843. try (Repository localDb = Git.cloneRepository().setDirectory(directory)
  844. .setURI(remoteDb.getDirectory().toURI().toString()).call()
  845. .getRepository()) {
  846. // The Hello file should not exist
  847. File hello = new File(localDb.getWorkTree(), "Hello");
  848. assertFalse("The Hello file shouldn't exist", hello.exists());
  849. // The Hello.txt file should exist
  850. File hellotxt = new File(localDb.getWorkTree(), "World.txt");
  851. assertTrue("The World.txt file should exist", hellotxt.exists());
  852. dotmodules = new File(localDb.getWorkTree(),
  853. Constants.DOT_GIT_MODULES);
  854. }
  855. // The .gitmodules file should have 'submodule "bar"' and shouldn't
  856. // have
  857. // 'submodule "foo"' lines.
  858. try (BufferedReader reader = Files
  859. .newBufferedReader(dotmodules.toPath(), UTF_8)) {
  860. boolean foo = false;
  861. boolean bar = false;
  862. while (true) {
  863. String line = reader.readLine();
  864. if (line == null)
  865. break;
  866. if (line.contains("submodule \"" + defaultUri + "\""))
  867. foo = true;
  868. if (line.contains("submodule \"" + notDefaultUri + "\""))
  869. bar = true;
  870. }
  871. assertTrue("The bar submodule should exist", bar);
  872. assertFalse("The foo submodule shouldn't exist", foo);
  873. }
  874. }
  875. @Test
  876. public void testRemoveOverlappingBare() throws Exception {
  877. Repository remoteDb = createBareRepository();
  878. Repository tempDb = createWorkRepository();
  879. StringBuilder xmlContent = new StringBuilder();
  880. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  881. .append("<manifest>")
  882. .append("<remote name=\"remote1\" fetch=\".\" />")
  883. .append("<default revision=\"master\" remote=\"remote1\" />")
  884. .append("<project path=\"foo/bar\" name=\"").append(groupBUri)
  885. .append("\" />").append("<project path=\"a\" name=\"")
  886. .append(groupAUri).append("\" />")
  887. .append("<project path=\"foo\" name=\"").append(defaultUri)
  888. .append("\" />").append("</manifest>");
  889. JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
  890. xmlContent.toString());
  891. RepoCommand command = new RepoCommand(remoteDb);
  892. command.setPath(
  893. tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
  894. .setURI(rootUri).call();
  895. // Clone it
  896. File directory = createTempDirectory("testRemoveOverlappingBare");
  897. File dotmodules;
  898. try (Repository localDb = Git.cloneRepository().setDirectory(directory)
  899. .setURI(remoteDb.getDirectory().toURI().toString()).call()
  900. .getRepository()) {
  901. dotmodules = new File(localDb.getWorkTree(),
  902. Constants.DOT_GIT_MODULES);
  903. }
  904. // Check .gitmodules file
  905. try (BufferedReader reader = Files
  906. .newBufferedReader(dotmodules.toPath(), UTF_8)) {
  907. boolean foo = false;
  908. boolean foobar = false;
  909. boolean a = false;
  910. while (true) {
  911. String line = reader.readLine();
  912. if (line == null)
  913. break;
  914. if (line.contains("submodule \"" + defaultUri + "\""))
  915. foo = true;
  916. if (line.contains("submodule \"" + groupBUri + "\""))
  917. foobar = true;
  918. if (line.contains("submodule \"" + groupAUri + "\""))
  919. a = true;
  920. }
  921. assertTrue("The " + defaultUri + " submodule should exist", foo);
  922. assertFalse("The " + groupBUri + " submodule shouldn't exist",
  923. foobar);
  924. assertTrue("The " + groupAUri + " submodule should exist", a);
  925. }
  926. }
  927. @Test
  928. public void testIncludeTag() throws Exception {
  929. Repository localDb = createWorkRepository();
  930. Repository tempDb = createWorkRepository();
  931. StringBuilder xmlContent = new StringBuilder();
  932. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  933. .append("<manifest>")
  934. .append("<include name=\"_include.xml\" />")
  935. .append("<default revision=\"master\" remote=\"remote1\" />")
  936. .append("</manifest>");
  937. JGitTestUtil.writeTrashFile(
  938. tempDb, "manifest.xml", xmlContent.toString());
  939. xmlContent = new StringBuilder();
  940. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  941. .append("<manifest>")
  942. .append("<remote name=\"remote1\" fetch=\".\" />")
  943. .append("<default revision=\"master\" remote=\"remote1\" />")
  944. .append("<project path=\"foo\" name=\"")
  945. .append(defaultUri)
  946. .append("\" />")
  947. .append("</manifest>");
  948. JGitTestUtil.writeTrashFile(
  949. tempDb, "_include.xml", xmlContent.toString());
  950. RepoCommand command = new RepoCommand(localDb);
  951. command
  952. .setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
  953. .setURI(rootUri)
  954. .call();
  955. File hello = new File(localDb.getWorkTree(), "foo/hello.txt");
  956. assertTrue("submodule should be checked out", hello.exists());
  957. try (BufferedReader reader = Files.newBufferedReader(hello.toPath(),
  958. UTF_8)) {
  959. String content = reader.readLine();
  960. assertEquals("submodule content should be as expected",
  961. "master world", content);
  962. }
  963. }
  964. @Test
  965. public void testRemoteAlias() throws Exception {
  966. StringBuilder xmlContent = new StringBuilder();
  967. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  968. .append("<manifest>")
  969. .append("<remote name=\"remote1\" fetch=\".\" alias=\"remote2\" />")
  970. .append("<default revision=\"master\" remote=\"remote2\" />")
  971. .append("<project path=\"foo\" name=\"")
  972. .append(defaultUri)
  973. .append("\" />")
  974. .append("</manifest>");
  975. Repository localDb = createWorkRepository();
  976. JGitTestUtil.writeTrashFile(
  977. localDb, "manifest.xml", xmlContent.toString());
  978. RepoCommand command = new RepoCommand(localDb);
  979. command
  980. .setPath(localDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
  981. .setURI(rootUri)
  982. .call();
  983. File file = new File(localDb.getWorkTree(), "foo/hello.txt");
  984. assertTrue("We should have foo", file.exists());
  985. }
  986. @Test
  987. public void testTargetBranch() throws Exception {
  988. Repository remoteDb1 = createBareRepository();
  989. Repository remoteDb2 = createBareRepository();
  990. Repository tempDb = createWorkRepository();
  991. StringBuilder xmlContent = new StringBuilder();
  992. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  993. .append("<manifest>")
  994. .append("<remote name=\"remote1\" fetch=\".\" />")
  995. .append("<default revision=\"master\" remote=\"remote1\" />")
  996. .append("<project path=\"foo\" name=\"").append(defaultUri)
  997. .append("\" />").append("</manifest>");
  998. JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
  999. xmlContent.toString());
  1000. RepoCommand command = new RepoCommand(remoteDb1);
  1001. command.setPath(
  1002. tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
  1003. .setURI(rootUri).setTargetBranch("test").call();
  1004. ObjectId branchId = remoteDb1
  1005. .resolve(Constants.R_HEADS + "test^{tree}");
  1006. command = new RepoCommand(remoteDb2);
  1007. command.setPath(
  1008. tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
  1009. .setURI(rootUri).call();
  1010. ObjectId defaultId = remoteDb2.resolve(Constants.HEAD + "^{tree}");
  1011. assertEquals(
  1012. "The tree id of branch db and default db should be the same",
  1013. branchId, defaultId);
  1014. }
  1015. @Test
  1016. public void testRecordRemoteBranch() throws Exception {
  1017. Repository remoteDb = createBareRepository();
  1018. Repository tempDb = createWorkRepository();
  1019. StringBuilder xmlContent = new StringBuilder();
  1020. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  1021. .append("<manifest>")
  1022. .append("<remote name=\"remote1\" fetch=\".\" />")
  1023. .append("<default revision=\"master\" remote=\"remote1\" />")
  1024. .append("<project path=\"with-branch\" ")
  1025. .append("revision=\"master\" ").append("name=\"")
  1026. .append(notDefaultUri).append("\" />")
  1027. .append("<project path=\"with-long-branch\" ")
  1028. .append("revision=\"refs/heads/master\" ").append("name=\"")
  1029. .append(defaultUri).append("\" />").append("</manifest>");
  1030. JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
  1031. xmlContent.toString());
  1032. RepoCommand command = new RepoCommand(remoteDb);
  1033. command.setPath(
  1034. tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
  1035. .setURI(rootUri).setRecordRemoteBranch(true).call();
  1036. // Clone it
  1037. File directory = createTempDirectory("testBareRepo");
  1038. try (Repository localDb = Git.cloneRepository().setDirectory(directory)
  1039. .setURI(remoteDb.getDirectory().toURI().toString()).call()
  1040. .getRepository();) {
  1041. // The .gitmodules file should exist
  1042. File gitmodules = new File(localDb.getWorkTree(), ".gitmodules");
  1043. assertTrue("The .gitmodules file should exist",
  1044. gitmodules.exists());
  1045. FileBasedConfig c = new FileBasedConfig(gitmodules, FS.DETECTED);
  1046. c.load();
  1047. assertEquals(
  1048. "Recording remote branches should work for short branch descriptions",
  1049. "master",
  1050. c.getString("submodule", notDefaultUri, "branch"));
  1051. assertEquals(
  1052. "Recording remote branches should work for full ref specs",
  1053. "refs/heads/master",
  1054. c.getString("submodule", defaultUri, "branch"));
  1055. }
  1056. }
  1057. @Test
  1058. public void testRecordSubmoduleLabels() throws Exception {
  1059. Repository remoteDb = createBareRepository();
  1060. Repository tempDb = createWorkRepository();
  1061. StringBuilder xmlContent = new StringBuilder();
  1062. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  1063. .append("<manifest>")
  1064. .append("<remote name=\"remote1\" fetch=\".\" />")
  1065. .append("<default revision=\"master\" remote=\"remote1\" />")
  1066. .append("<project path=\"test\" ")
  1067. .append("revision=\"master\" ").append("name=\"")
  1068. .append(notDefaultUri).append("\" ")
  1069. .append("groups=\"a1,a2\" />").append("</manifest>");
  1070. JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
  1071. xmlContent.toString());
  1072. RepoCommand command = new RepoCommand(remoteDb);
  1073. command.setPath(
  1074. tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
  1075. .setURI(rootUri).setRecordSubmoduleLabels(true).call();
  1076. // Clone it
  1077. File directory = createTempDirectory("testBareRepo");
  1078. try (Repository localDb = Git.cloneRepository().setDirectory(directory)
  1079. .setURI(remoteDb.getDirectory().toURI().toString()).call()
  1080. .getRepository();) {
  1081. // The .gitattributes file should exist
  1082. File gitattributes = new File(localDb.getWorkTree(),
  1083. ".gitattributes");
  1084. assertTrue("The .gitattributes file should exist",
  1085. gitattributes.exists());
  1086. try (BufferedReader reader = Files
  1087. .newBufferedReader(gitattributes.toPath(),
  1088. UTF_8)) {
  1089. String content = reader.readLine();
  1090. assertEquals(".gitattributes content should be as expected",
  1091. "/test a1 a2", content);
  1092. }
  1093. }
  1094. }
  1095. @Test
  1096. public void testRecordShallowRecommendation() throws Exception {
  1097. Repository remoteDb = createBareRepository();
  1098. Repository tempDb = createWorkRepository();
  1099. StringBuilder xmlContent = new StringBuilder();
  1100. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  1101. .append("<manifest>")
  1102. .append("<remote name=\"remote1\" fetch=\".\" />")
  1103. .append("<default revision=\"master\" remote=\"remote1\" />")
  1104. .append("<project path=\"shallow-please\" ").append("name=\"")
  1105. .append(defaultUri).append("\" ").append("clone-depth=\"1\" />")
  1106. .append("<project path=\"non-shallow\" ").append("name=\"")
  1107. .append(notDefaultUri).append("\" />").append("</manifest>");
  1108. JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
  1109. xmlContent.toString());
  1110. RepoCommand command = new RepoCommand(remoteDb);
  1111. command.setPath(
  1112. tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
  1113. .setURI(rootUri).setRecommendShallow(true).call();
  1114. // Clone it
  1115. File directory = createTempDirectory("testBareRepo");
  1116. try (Repository localDb = Git.cloneRepository().setDirectory(directory)
  1117. .setURI(remoteDb.getDirectory().toURI().toString()).call()
  1118. .getRepository();) {
  1119. // The .gitmodules file should exist
  1120. File gitmodules = new File(localDb.getWorkTree(), ".gitmodules");
  1121. assertTrue("The .gitmodules file should exist",
  1122. gitmodules.exists());
  1123. FileBasedConfig c = new FileBasedConfig(gitmodules, FS.DETECTED);
  1124. c.load();
  1125. assertEquals("Recording shallow configuration should work", "true",
  1126. c.getString("submodule", defaultUri, "shallow"));
  1127. assertNull("Recording non shallow configuration should work",
  1128. c.getString("submodule", notDefaultUri, "shallow"));
  1129. }
  1130. }
  1131. @Test
  1132. public void testRemoteRevision() throws Exception {
  1133. StringBuilder xmlContent = new StringBuilder();
  1134. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  1135. .append("<manifest>")
  1136. .append("<remote name=\"remote1\" fetch=\".\" />")
  1137. .append("<remote name=\"remote2\" fetch=\".\" revision=\"")
  1138. .append(BRANCH)
  1139. .append("\" />")
  1140. .append("<default remote=\"remote1\" revision=\"master\" />")
  1141. .append("<project path=\"foo\" remote=\"remote2\" name=\"")
  1142. .append(defaultUri)
  1143. .append("\" />")
  1144. .append("</manifest>");
  1145. writeTrashFile("manifest.xml", xmlContent.toString());
  1146. RepoCommand command = new RepoCommand(db);
  1147. command.setPath(db.getWorkTree().getAbsolutePath() + "/manifest.xml")
  1148. .setURI(rootUri)
  1149. .call();
  1150. File hello = new File(db.getWorkTree(), "foo/hello.txt");
  1151. assertContents(hello.toPath(), "branch world");
  1152. }
  1153. @Test
  1154. public void testDefaultRemoteRevision() throws Exception {
  1155. StringBuilder xmlContent = new StringBuilder();
  1156. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  1157. .append("<manifest>")
  1158. .append("<remote name=\"remote1\" fetch=\".\" revision=\"")
  1159. .append(BRANCH)
  1160. .append("\" />")
  1161. .append("<default remote=\"remote1\" />")
  1162. .append("<project path=\"foo\" name=\"")
  1163. .append(defaultUri)
  1164. .append("\" />")
  1165. .append("</manifest>");
  1166. writeTrashFile("manifest.xml", xmlContent.toString());
  1167. RepoCommand command = new RepoCommand(db);
  1168. command.setPath(db.getWorkTree().getAbsolutePath() + "/manifest.xml")
  1169. .setURI(rootUri)
  1170. .call();
  1171. File hello = new File(db.getWorkTree(), "foo/hello.txt");
  1172. try (BufferedReader reader = Files.newBufferedReader(hello.toPath(),
  1173. UTF_8)) {
  1174. String content = reader.readLine();
  1175. assertEquals("submodule content should be as expected",
  1176. "branch world", content);
  1177. }
  1178. }
  1179. @Test
  1180. public void testTwoPathUseTheSameName() throws Exception {
  1181. Repository remoteDb = createBareRepository();
  1182. Repository tempDb = createWorkRepository();
  1183. StringBuilder xmlContent = new StringBuilder();
  1184. xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
  1185. .append("<manifest>")
  1186. .append("<remote name=\"remote1\" fetch=\".\" />")
  1187. .append("<default revision=\"master\" remote=\"remote1\" />")
  1188. .append("<project path=\"path1\" ").append("name=\"")
  1189. .append(defaultUri).append("\" />")
  1190. .append("<project path=\"path2\" ").append("name=\"")
  1191. .append(defaultUri).append("\" />").append("</manifest>");
  1192. JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
  1193. xmlContent.toString());
  1194. RepoCommand command = new RepoCommand(remoteDb);
  1195. command.setPath(
  1196. tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
  1197. .setURI(rootUri).setRecommendShallow(true).call();
  1198. File directory = createTempDirectory("testBareRepo");
  1199. try (Repository localDb = Git.cloneRepository().setDirectory(directory)
  1200. .setURI(remoteDb.getDirectory().toURI().toString()).call()
  1201. .getRepository();) {
  1202. File gitmodules = new File(localDb.getWorkTree(), ".gitmodules");
  1203. assertTrue("The .gitmodules file should exist",
  1204. gitmodules.exists());
  1205. FileBasedConfig c = new FileBasedConfig(gitmodules, FS.DETECTED);
  1206. c.load();
  1207. assertEquals("A module should exist for path1", "path1",
  1208. c.getString("submodule", defaultUri + "/path1", "path"));
  1209. assertEquals("A module should exist for path2", "path2",
  1210. c.getString("submodule", defaultUri + "/path2", "path"));
  1211. }
  1212. }
  1213. private void resolveRelativeUris() {
  1214. // Find the longest common prefix ends with "/" as rootUri.
  1215. defaultUri = defaultDb.getDirectory().toURI().toString();
  1216. notDefaultUri = notDefaultDb.getDirectory().toURI().toString();
  1217. groupAUri = groupADb.getDirectory().toURI().toString();
  1218. groupBUri = groupBDb.getDirectory().toURI().toString();
  1219. int start = 0;
  1220. while (start <= defaultUri.length()) {
  1221. int newStart = defaultUri.indexOf('/', start + 1);
  1222. String prefix = defaultUri.substring(0, newStart);
  1223. if (!notDefaultUri.startsWith(prefix) ||
  1224. !groupAUri.startsWith(prefix) ||
  1225. !groupBUri.startsWith(prefix)) {
  1226. start++;
  1227. rootUri = defaultUri.substring(0, start) + "manifest";
  1228. defaultUri = defaultUri.substring(start);
  1229. notDefaultUri = notDefaultUri.substring(start);
  1230. groupAUri = groupAUri.substring(start);
  1231. groupBUri = groupBUri.substring(start);
  1232. return;
  1233. }
  1234. start = newStart;
  1235. }
  1236. }
  1237. void testRelative(String a, String b, String want) {
  1238. String got = RepoCommand.relativize(URI.create(a), URI.create(b)).toString();
  1239. if (!got.equals(want)) {
  1240. fail(String.format("relative('%s', '%s') = '%s', want '%s'", a, b, got, want));
  1241. }
  1242. }
  1243. @Test
  1244. public void relative() {
  1245. testRelative("a/b/", "a/", "../");
  1246. // Normalization:
  1247. testRelative("a/p/..//b/", "a/", "../");
  1248. testRelative("a/b", "a/", "");
  1249. testRelative("a/", "a/b/", "b/");
  1250. testRelative("a/", "a/b", "b");
  1251. testRelative("/a/b/c", "/b/c", "../../b/c");
  1252. testRelative("/abc", "bcd", "bcd");
  1253. testRelative("abc", "def", "def");
  1254. testRelative("abc", "/bcd", "/bcd");
  1255. testRelative("http://a", "a/b", "a/b");
  1256. testRelative("http://base.com/a/", "http://child.com/a/b", "http://child.com/a/b");
  1257. testRelative("http://base.com/a/", "http://base.com/a/b", "b");
  1258. }
  1259. }