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