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