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