1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.internal.storage.file;
12
13 import static org.eclipse.jgit.lib.RefUpdate.Result.FAST_FORWARD;
14 import static org.eclipse.jgit.lib.RefUpdate.Result.FORCED;
15 import static org.eclipse.jgit.lib.RefUpdate.Result.IO_FAILURE;
16 import static org.eclipse.jgit.lib.RefUpdate.Result.LOCK_FAILURE;
17 import static org.junit.Assert.assertEquals;
18 import static org.junit.Assert.assertFalse;
19 import static org.junit.Assert.assertNotEquals;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertNotSame;
22 import static org.junit.Assert.assertNull;
23 import static org.junit.Assert.assertSame;
24 import static org.junit.Assert.assertTrue;
25 import static org.junit.Assert.fail;
26
27 import java.io.File;
28 import java.io.FileOutputStream;
29 import java.io.IOException;
30 import java.io.OutputStream;
31 import java.security.SecureRandom;
32 import java.util.ArrayList;
33 import java.util.Collection;
34 import java.util.HashSet;
35 import java.util.List;
36
37 import java.util.Set;
38 import org.eclipse.jgit.lib.AnyObjectId;
39 import org.eclipse.jgit.lib.Constants;
40 import org.eclipse.jgit.lib.NullProgressMonitor;
41 import org.eclipse.jgit.lib.ObjectId;
42 import org.eclipse.jgit.lib.PersonIdent;
43 import org.eclipse.jgit.lib.Ref;
44 import org.eclipse.jgit.lib.RefDatabase;
45 import org.eclipse.jgit.lib.RefRename;
46 import org.eclipse.jgit.lib.RefUpdate;
47 import org.eclipse.jgit.lib.RefUpdate.Result;
48 import org.eclipse.jgit.lib.ReflogEntry;
49 import org.eclipse.jgit.lib.ReflogReader;
50 import org.eclipse.jgit.lib.RepositoryCache;
51 import org.eclipse.jgit.revwalk.RevWalk;
52 import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
53 import org.eclipse.jgit.transport.ReceiveCommand;
54 import org.junit.Test;
55
56 public class FileReftableTest extends SampleDataRepositoryTestCase {
57 String bCommit;
58
59 @Override
60 public void setUp() throws Exception {
61 super.setUp();
62 Ref b = db.exactRef("refs/heads/b");
63 bCommit = b.getObjectId().getName();
64 db.convertToReftable(false, false);
65 }
66
67 @SuppressWarnings("boxing")
68 @Test
69 public void testRacyReload() throws Exception {
70 ObjectId id = db.resolve("master");
71 int retry = 0;
72 try (FileRepository repo1 = new FileRepository(db.getDirectory());
73 FileRepository repo2 = new FileRepository(db.getDirectory())) {
74 FileRepository repos[] = { repo1, repo2 };
75 for (int i = 0; i < 10; i++) {
76 for (int j = 0; j < 2; j++) {
77 FileRepository repo = repos[j];
78 RefUpdate u = repo.getRefDatabase().newUpdate(
79 String.format("branch%d", i * 10 + j), false);
80
81 u.setNewObjectId(id);
82 RefUpdate.Result r = u.update();
83 if (!r.equals(Result.NEW)) {
84 retry++;
85 u = repo.getRefDatabase().newUpdate(
86 String.format("branch%d", i * 10 + j), false);
87
88 u.setNewObjectId(id);
89 r = u.update();
90 assertEquals(r, Result.NEW);
91 }
92 }
93 }
94
95
96 assertEquals(retry, 19);
97 }
98 }
99
100 @Test
101 public void testCompactFully() throws Exception {
102 ObjectId c1 = db.resolve("master^^");
103 ObjectId c2 = db.resolve("master^");
104 for (int i = 0; i < 5; i++) {
105 RefUpdate u = db.updateRef("refs/heads/master");
106 u.setForceUpdate(true);
107 u.setNewObjectId((i%2) == 0 ? c1 : c2);
108 assertEquals(u.update(), FORCED);
109 }
110
111 File tableDir = new File(db.getDirectory(), Constants.REFTABLE);
112 assertTrue(tableDir.listFiles().length > 2);
113 ((FileReftableDatabase)db.getRefDatabase()).compactFully();
114 assertEquals(tableDir.listFiles().length,2);
115 }
116
117 @Test
118 public void testOpenConvert() throws Exception {
119 try (FileRepository repo = new FileRepository(db.getDirectory())) {
120 assertTrue(repo.getRefDatabase() instanceof FileReftableDatabase);
121 }
122 }
123
124 @Test
125 public void testConvert() throws Exception {
126 Ref h = db.exactRef("HEAD");
127 assertTrue(h.isSymbolic());
128 assertEquals("refs/heads/master", h.getTarget().getName());
129
130 Ref b = db.exactRef("refs/heads/b");
131 assertFalse(b.isSymbolic());
132 assertTrue(b.isPeeled());
133 assertEquals(bCommit, b.getObjectId().name());
134
135 assertTrue(db.getRefDatabase().hasFastTipsWithSha1());
136 }
137
138
139 @Test
140 public void testConvertBrokenObjectId() throws Exception {
141 db.convertToPackedRefs(false, false);
142 new File(db.getDirectory(), "refs/heads").mkdirs();
143
144 String invalidId = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
145 File headFile = new File(db.getDirectory(), "refs/heads/broken");
146 try (OutputStream os = new FileOutputStream(headFile)) {
147 os.write(Constants.encodeASCII(invalidId + "\n"));
148 }
149
150 Ref r = db.exactRef("refs/heads/broken");
151 assertNotNull(r);
152 db.convertToReftable(true, false);
153 }
154
155 @Test
156 public void testConvertToRefdirReflog() throws Exception {
157 Ref a = db.exactRef("refs/heads/a");
158 String aCommit = a.getObjectId().getName();
159 RefUpdate u = db.updateRef("refs/heads/master");
160 u.setForceUpdate(true);
161 u.setNewObjectId(ObjectId.fromString(aCommit));
162 u.setForceRefLog(true);
163 u.setRefLogMessage("apple", false);
164 u.update();
165
166 RefUpdate v = db.updateRef("refs/heads/master");
167 v.setForceUpdate(true);
168 v.setNewObjectId(ObjectId.fromString(bCommit));
169 v.setForceRefLog(true);
170 v.setRefLogMessage("banana", false);
171 v.update();
172
173 db.convertToPackedRefs(true, false);
174 List<ReflogEntry> logs = db.getReflogReader("refs/heads/master").getReverseEntries(2);
175 assertEquals(logs.get(0).getComment(), "banana");
176 assertEquals(logs.get(1).getComment(), "apple");
177 }
178
179 @Test
180 public void testBatchrefUpdate() throws Exception {
181 ObjectId cur = db.resolve("master");
182 ObjectId prev = db.resolve("master^");
183
184 PersonIdent person = new PersonIdent("name", "mail@example.com");
185 ReceiveCommand rc1 = new ReceiveCommand(ObjectId.zeroId(), cur, "refs/heads/batch1");
186 ReceiveCommand rc2 = new ReceiveCommand(ObjectId.zeroId(), prev, "refs/heads/batch2");
187 String msg = "message";
188 try (RevWalk rw = new RevWalk(db)) {
189 db.getRefDatabase().newBatchUpdate()
190 .addCommand(rc1, rc2)
191 .setAtomic(true)
192 .setRefLogIdent(person)
193 .setRefLogMessage(msg, false)
194 .execute(rw, NullProgressMonitor.INSTANCE);
195 }
196
197 assertEquals(rc1.getResult(), ReceiveCommand.Result.OK);
198 assertEquals(rc2.getResult(), ReceiveCommand.Result.OK);
199
200 ReflogEntry e = db.getReflogReader("refs/heads/batch1").getLastEntry();
201 assertEquals(msg, e.getComment());
202 assertEquals(person, e.getWho());
203 assertEquals(cur, e.getNewId());
204
205 e = db.getReflogReader("refs/heads/batch2").getLastEntry();
206 assertEquals(msg, e.getComment());
207 assertEquals(person, e.getWho());
208 assertEquals(prev, e.getNewId());
209
210 assertEquals(cur, db.exactRef("refs/heads/batch1").getObjectId());
211 assertEquals(prev, db.exactRef("refs/heads/batch2").getObjectId());
212 }
213
214 @Test
215 public void testFastforwardStatus() throws Exception {
216 ObjectId cur = db.resolve("master");
217 ObjectId prev = db.resolve("master^");
218 RefUpdate u = db.updateRef("refs/heads/master");
219
220 u.setNewObjectId(prev);
221 u.setForceUpdate(true);
222 assertEquals(FORCED, u.update());
223
224 RefUpdate u2 = db.updateRef("refs/heads/master");
225
226 u2.setNewObjectId(cur);
227 assertEquals(FAST_FORWARD, u2.update());
228 }
229
230 @Test
231 public void testUpdateChecksOldValue() throws Exception {
232 ObjectId cur = db.resolve("master");
233 ObjectId prev = db.resolve("master^");
234 RefUpdate u1 = db.updateRef("refs/heads/master");
235 RefUpdate u2 = db.updateRef("refs/heads/master");
236
237 u1.setExpectedOldObjectId(cur);
238 u1.setNewObjectId(prev);
239 u1.setForceUpdate(true);
240
241 u2.setExpectedOldObjectId(cur);
242 u2.setNewObjectId(prev);
243 u2.setForceUpdate(true);
244
245 assertEquals(FORCED, u1.update());
246 assertEquals(LOCK_FAILURE, u2.update());
247 }
248
249 @Test
250 public void testWritesymref() throws Exception {
251 writeSymref(Constants.HEAD, "refs/heads/a");
252 assertNotNull(db.exactRef("refs/heads/b"));
253 }
254
255 @Test
256 public void testFastforwardStatus2() throws Exception {
257 writeSymref(Constants.HEAD, "refs/heads/a");
258 ObjectId bId = db.exactRef("refs/heads/b").getObjectId();
259 RefUpdate u = db.updateRef("refs/heads/a");
260 u.setNewObjectId(bId);
261 u.setRefLogMessage("Setup", false);
262 assertEquals(FAST_FORWARD, u.update());
263 }
264
265 @Test
266 public void testDelete() throws Exception {
267 RefUpdate up = db.getRefDatabase().newUpdate("refs/heads/a", false);
268 up.setForceUpdate(true);
269 RefUpdate.Result res = up.delete();
270 assertEquals(res, FORCED);
271 assertNull(db.exactRef("refs/heads/a"));
272 }
273
274 @Test
275 public void testDeleteWithoutHead() throws IOException {
276
277 RefUpdate refUpdate = db.updateRef(Constants.HEAD, true);
278 refUpdate.setForceUpdate(true);
279 refUpdate.setNewObjectId(ObjectId.zeroId());
280
281 RefUpdate.Result updateResult = refUpdate.update();
282 assertEquals(FORCED, updateResult);
283
284 Ref r = db.exactRef("HEAD");
285 assertEquals(ObjectId.zeroId(), r.getObjectId());
286 RefUpdate.Result deleteHeadResult = db.updateRef(Constants.HEAD)
287 .delete();
288
289
290 assertEquals(RefUpdate.Result.NO_CHANGE, deleteHeadResult);
291
292
293 db.updateRef(Constants.R_HEADS + "master").delete();
294 }
295
296 @Test
297 public void testUpdateRefDetached() throws Exception {
298 ObjectId pid = db.resolve("refs/heads/master");
299 ObjectId ppid = db.resolve("refs/heads/master^");
300 RefUpdate updateRef = db.updateRef("HEAD", true);
301 updateRef.setForceUpdate(true);
302 updateRef.setNewObjectId(ppid);
303 RefUpdate.Result update = updateRef.update();
304 assertEquals(FORCED, update);
305 assertEquals(ppid, db.resolve("HEAD"));
306 Ref ref = db.exactRef("HEAD");
307 assertEquals("HEAD", ref.getName());
308 assertTrue("is detached", !ref.isSymbolic());
309
310
311 assertEquals(pid, db.resolve("refs/heads/master"));
312 ReflogReader reflogReader = db.getReflogReader("HEAD");
313 ReflogEntry e = reflogReader.getReverseEntries().get(0);
314 assertEquals(ppid, e.getNewId());
315 assertEquals("GIT_COMMITTER_EMAIL", e.getWho().getEmailAddress());
316 assertEquals("GIT_COMMITTER_NAME", e.getWho().getName());
317 assertEquals(1250379778000L, e.getWho().getWhen().getTime());
318 assertEquals(pid, e.getOldId());
319 }
320
321 @Test
322 public void testWriteReflog() throws Exception {
323 ObjectId pid = db.resolve("refs/heads/master^");
324 RefUpdate updateRef = db.updateRef("refs/heads/master");
325 updateRef.setNewObjectId(pid);
326 String msg = "REFLOG!";
327 updateRef.setRefLogMessage(msg, true);
328 PersonIdent person = new PersonIdent("name", "mail@example.com");
329 updateRef.setRefLogIdent(person);
330 updateRef.setForceUpdate(true);
331 RefUpdate.Result update = updateRef.update();
332 assertEquals(FORCED, update);
333 ReflogReader r = db.getReflogReader("refs/heads/master");
334
335 ReflogEntry e = r.getLastEntry();
336 assertEquals(e.getNewId(), pid);
337 assertEquals(e.getComment(), "REFLOG!: FORCED");
338 assertEquals(e.getWho(), person);
339 }
340
341 @Test
342 public void testLooseDelete() throws IOException {
343 final String newRef = "refs/heads/abc";
344 assertNull(db.exactRef(newRef));
345
346 RefUpdate ref = db.updateRef(newRef);
347 ObjectId nonZero = db.resolve(Constants.HEAD);
348 assertNotEquals(nonZero, ObjectId.zeroId());
349 ref.setNewObjectId(nonZero);
350 assertEquals(RefUpdate.Result.NEW, ref.update());
351
352 ref = db.updateRef(newRef);
353 ref.setNewObjectId(db.resolve(Constants.HEAD));
354
355 assertEquals(ref.delete(), RefUpdate.Result.NO_CHANGE);
356
357
358 ReflogReader reader = db.getReflogReader("refs/heads/abc");
359 assertEquals(ObjectId.zeroId(), reader.getReverseEntry(1).getOldId());
360 assertEquals(nonZero, reader.getReverseEntry(1).getNewId());
361 assertEquals(nonZero, reader.getReverseEntry(0).getOldId());
362 assertEquals(ObjectId.zeroId(), reader.getReverseEntry(0).getNewId());
363 }
364
365 private static class SubclassedId extends ObjectId {
366 SubclassedId(AnyObjectId src) {
367 super(src);
368 }
369 }
370
371 @Test
372 public void testNoCacheObjectIdSubclass() throws IOException {
373 final String newRef = "refs/heads/abc";
374 final RefUpdate ru = updateRef(newRef);
375 final SubclassedId newid = new SubclassedId(ru.getNewObjectId());
376 ru.setNewObjectId(newid);
377 RefUpdate.Result update = ru.update();
378 assertEquals(RefUpdate.Result.NEW, update);
379 Ref r = db.exactRef(newRef);
380 assertEquals(newRef, r.getName());
381 assertNotNull(r.getObjectId());
382 assertNotSame(newid, r.getObjectId());
383 assertSame(ObjectId.class, r.getObjectId().getClass());
384 assertEquals(newid, r.getObjectId());
385 List<ReflogEntry> reverseEntries1 = db.getReflogReader("refs/heads/abc")
386 .getReverseEntries();
387 ReflogEntry entry1 = reverseEntries1.get(0);
388 assertEquals(1, reverseEntries1.size());
389 assertEquals(ObjectId.zeroId(), entry1.getOldId());
390 assertEquals(r.getObjectId(), entry1.getNewId());
391
392 assertEquals(new PersonIdent(db).toString(),
393 entry1.getWho().toString());
394 assertEquals("", entry1.getComment());
395 List<ReflogEntry> reverseEntries2 = db.getReflogReader("HEAD")
396 .getReverseEntries();
397 assertEquals(0, reverseEntries2.size());
398 }
399
400 @Test
401 public void testDeleteSymref() throws IOException {
402 RefUpdate dst = updateRef("refs/heads/abc");
403 assertEquals(RefUpdate.Result.NEW, dst.update());
404 ObjectId id = dst.getNewObjectId();
405
406 RefUpdate u = db.updateRef("refs/symref");
407 assertEquals(RefUpdate.Result.NEW, u.link(dst.getName()));
408
409 Ref ref = db.exactRef(u.getName());
410 assertNotNull(ref);
411 assertTrue(ref.isSymbolic());
412 assertEquals(dst.getName(), ref.getLeaf().getName());
413 assertEquals(id, ref.getLeaf().getObjectId());
414
415 u = db.updateRef(u.getName());
416 u.setDetachingSymbolicRef();
417 u.setForceUpdate(true);
418 assertEquals(FORCED, u.delete());
419
420 assertNull(db.exactRef(u.getName()));
421 ref = db.exactRef(dst.getName());
422 assertNotNull(ref);
423 assertFalse(ref.isSymbolic());
424 assertEquals(id, ref.getObjectId());
425 }
426
427 @Test
428 public void writeUnbornHead() throws Exception {
429 RefUpdate.Result r = db.updateRef("HEAD").link("refs/heads/unborn");
430 assertEquals(FORCED, r);
431
432 Ref head = db.exactRef("HEAD");
433 assertTrue(head.isSymbolic());
434 assertEquals(head.getTarget().getName(), "refs/heads/unborn");
435 }
436
437
438
439
440
441
442 @Test
443 public void testUpdateRefDetachedUnbornHead() throws Exception {
444 ObjectId ppid = db.resolve("refs/heads/master^");
445 writeSymref("HEAD", "refs/heads/unborn");
446 RefUpdate updateRef = db.updateRef("HEAD", true);
447 updateRef.setForceUpdate(true);
448 updateRef.setNewObjectId(ppid);
449 RefUpdate.Result update = updateRef.update();
450 assertEquals(RefUpdate.Result.NEW, update);
451 assertEquals(ppid, db.resolve("HEAD"));
452 Ref ref = db.exactRef("HEAD");
453 assertEquals("HEAD", ref.getName());
454 assertTrue("is detached", !ref.isSymbolic());
455
456
457 assertNull(db.resolve("refs/heads/unborn"));
458 ReflogReader reflogReader = db.getReflogReader("HEAD");
459 ReflogEntry e = reflogReader.getReverseEntries().get(0);
460 assertEquals(ObjectId.zeroId(), e.getOldId());
461 assertEquals(ppid, e.getNewId());
462 assertEquals("GIT_COMMITTER_EMAIL", e.getWho().getEmailAddress());
463 assertEquals("GIT_COMMITTER_NAME", e.getWho().getName());
464 assertEquals(1250379778000L, e.getWho().getWhen().getTime());
465 }
466
467 @Test
468 public void testDeleteNotFound() throws IOException {
469 RefUpdate ref = updateRef("refs/heads/doesnotexist");
470 assertNull(db.exactRef(ref.getName()));
471 assertEquals(RefUpdate.Result.NEW, ref.delete());
472 assertNull(db.exactRef(ref.getName()));
473 }
474
475 @Test
476 public void testRenameSymref() throws IOException {
477 db.resolve("HEAD");
478 RefRename r = db.renameRef("HEAD", "KOPF");
479 assertEquals(IO_FAILURE, r.rename());
480 }
481
482 @Test
483 public void testRenameCurrentBranch() throws IOException {
484 ObjectId rb = db.resolve("refs/heads/b");
485 writeSymref(Constants.HEAD, "refs/heads/b");
486 ObjectId oldHead = db.resolve(Constants.HEAD);
487 assertEquals("internal test condition, b == HEAD", oldHead, rb);
488 RefRename renameRef = db.renameRef("refs/heads/b",
489 "refs/heads/new/name");
490 RefUpdate.Result result = renameRef.rename();
491 assertEquals(RefUpdate.Result.RENAMED, result);
492 assertEquals(rb, db.resolve("refs/heads/new/name"));
493 assertNull(db.resolve("refs/heads/b"));
494 assertEquals(rb, db.resolve(Constants.HEAD));
495
496 List<String> names = new ArrayList<>();
497 names.add("HEAD");
498 names.add("refs/heads/b");
499 names.add("refs/heads/new/name");
500
501 for (String nm : names) {
502 ReflogReader rd = db.getReflogReader(nm);
503 assertNotNull(rd);
504 ReflogEntry last = rd.getLastEntry();
505 ObjectId id = last.getNewId();
506 assertTrue(ObjectId.zeroId().equals(id) || rb.equals(id));
507
508 id = last.getNewId();
509 assertTrue(ObjectId.zeroId().equals(id) || rb.equals(id));
510
511 String want = "Branch: renamed b to new/name";
512 assertEquals(want, last.getComment());
513 }
514 }
515
516 @Test
517 public void isGitRepository() {
518 assertTrue(RepositoryCache.FileKey.isGitRepository(db.getDirectory(), db.getFS()));
519 }
520
521 @Test
522 public void testRenameDestExists() throws IOException {
523 ObjectId rb = db.resolve("refs/heads/b");
524 writeSymref(Constants.HEAD, "refs/heads/b");
525 ObjectId oldHead = db.resolve(Constants.HEAD);
526 assertEquals("internal test condition, b == HEAD", oldHead, rb);
527 RefRename renameRef = db.renameRef("refs/heads/b", "refs/heads/a");
528 RefUpdate.Result result = renameRef.rename();
529 assertEquals(RefUpdate.Result.LOCK_FAILURE, result);
530 }
531
532 @Test
533 public void testRenameAtomic() throws IOException {
534 ObjectId prevId = db.resolve("refs/heads/master^");
535
536 RefRename rename = db.renameRef("refs/heads/master",
537 "refs/heads/newmaster");
538
539 RefUpdate updateRef = db.updateRef("refs/heads/master");
540 updateRef.setNewObjectId(prevId);
541 updateRef.setForceUpdate(true);
542 assertEquals(FORCED, updateRef.update());
543 assertEquals(RefUpdate.Result.LOCK_FAILURE, rename.rename());
544 }
545
546 @Test
547 public void compactFully() throws Exception {
548 FileReftableDatabase refDb = (FileReftableDatabase) db.getRefDatabase();
549 PersonIdent person = new PersonIdent("jane", "jane@invalid");
550
551 ObjectId aId = db.exactRef("refs/heads/a").getObjectId();
552 ObjectId bId = db.exactRef("refs/heads/b").getObjectId();
553
554 SecureRandom random = new SecureRandom();
555 List<String> strs = new ArrayList<>();
556 for (int i = 0; i < 1024; i++) {
557 strs.add(String.format("%02x",
558 Integer.valueOf(random.nextInt(256))));
559 }
560
561 String randomStr = String.join("", strs);
562 String refName = "branch";
563 for (long i = 0; i < 2; i++) {
564 RefUpdate ru = refDb.newUpdate(refName, false);
565 ru.setNewObjectId(i % 2 == 0 ? aId : bId);
566 ru.setForceUpdate(true);
567
568
569 ru.setRefLogMessage(i == 0 ? randomStr : "short", false);
570 ru.setRefLogIdent(person);
571
572 RefUpdate.Result res = ru.update();
573 assertTrue(res == Result.NEW || res == FORCED);
574 }
575
576 assertEquals(refDb.exactRef(refName).getObjectId(), bId);
577 assertTrue(randomStr.equals(refDb.getReflogReader(refName).getReverseEntry(1).getComment()));
578 refDb.compactFully();
579 assertEquals(refDb.exactRef(refName).getObjectId(), bId);
580 assertTrue(randomStr.equals(refDb.getReflogReader(refName).getReverseEntry(1).getComment()));
581 }
582
583 @Test
584 public void reftableRefsStorageClass() throws IOException {
585 Ref b = db.exactRef("refs/heads/b");
586 assertEquals(Ref.Storage.PACKED, b.getStorage());
587 }
588
589 @Test
590 public void testGetRefsExcludingPrefix() throws IOException {
591 Set<String> prefixes = new HashSet<>();
592 prefixes.add("refs/tags");
593
594 List<Ref> refs =
595 db.getRefDatabase().getRefsByPrefixWithExclusions(RefDatabase.ALL, prefixes);
596 assertEquals(13, refs.size());
597 checkContainsRef(refs, db.exactRef("HEAD"));
598 checkContainsRef(refs, db.exactRef("refs/heads/a"));
599 for (Ref notInResult : db.getRefDatabase().getRefsByPrefix("refs/tags")) {
600 assertFalse(refs.contains(notInResult));
601 }
602 }
603
604 @Test
605 public void testGetRefsExcludingPrefixes() throws IOException {
606 Set<String> exclude = new HashSet<>();
607 exclude.add("refs/tags/");
608 exclude.add("refs/heads/");
609 List<Ref> refs = db.getRefDatabase().getRefsByPrefixWithExclusions(RefDatabase.ALL, exclude);
610 assertEquals(1, refs.size());
611 checkContainsRef(refs, db.exactRef("HEAD"));
612 }
613
614 @Test
615 public void testGetRefsExcludingNonExistingPrefixes() throws IOException {
616 Set<String> exclude = new HashSet<>();
617 exclude.add("refs/tags/");
618 exclude.add("refs/heads/");
619 exclude.add("refs/nonexistent/");
620 List<Ref> refs = db.getRefDatabase().getRefsByPrefixWithExclusions(RefDatabase.ALL, exclude);
621 assertEquals(1, refs.size());
622 checkContainsRef(refs, db.exactRef("HEAD"));
623 }
624
625 @Test
626 public void testGetRefsWithPrefixExcludingPrefixes() throws IOException {
627 Set<String> exclude = new HashSet<>();
628 exclude.add("refs/heads/pa");
629 String include = "refs/heads/p";
630 List<Ref> refs = db.getRefDatabase().getRefsByPrefixWithExclusions(include, exclude);
631 assertEquals(1, refs.size());
632 checkContainsRef(refs, db.exactRef("refs/heads/prefix/a"));
633 }
634
635 @Test
636 public void testGetRefsWithPrefixExcludingOverlappingPrefixes() throws IOException {
637 Set<String> exclude = new HashSet<>();
638 exclude.add("refs/heads/pa");
639 exclude.add("refs/heads/");
640 exclude.add("refs/heads/p");
641 exclude.add("refs/tags/");
642 List<Ref> refs = db.getRefDatabase().getRefsByPrefixWithExclusions(RefDatabase.ALL, exclude);
643 assertEquals(1, refs.size());
644 checkContainsRef(refs, db.exactRef("HEAD"));
645 }
646
647 private RefUpdate updateRef(String name) throws IOException {
648 final RefUpdate ref = db.updateRef(name);
649 ref.setNewObjectId(db.resolve(Constants.HEAD));
650 return ref;
651 }
652
653 private void writeSymref(String src, String dst) throws IOException {
654 RefUpdate u = db.updateRef(src);
655 switch (u.link(dst)) {
656 case NEW:
657 case FORCED:
658 case NO_CHANGE:
659 break;
660 default:
661 fail("link " + src + " to " + dst);
662 }
663 }
664
665 private static void checkContainsRef(Collection<Ref> haystack, Ref needle) {
666 for (Ref ref : haystack) {
667 if (ref.getName().equals(needle.getName()) &&
668 ref.getObjectId().equals(needle.getObjectId())) {
669 return;
670 }
671 }
672 fail("list " + haystack + " does not contain ref " + needle);
673 }
674 }