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.

RepoCommandTest.java 51KB

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