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