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.attributes;
44
45 import static org.junit.Assert.assertEquals;
46 import static org.junit.Assert.assertFalse;
47 import static org.junit.Assert.assertTrue;
48
49 import java.io.File;
50 import java.io.IOException;
51 import java.util.ArrayList;
52 import java.util.Collection;
53 import java.util.Collections;
54 import java.util.HashSet;
55 import java.util.List;
56 import java.util.Set;
57
58 import org.eclipse.jgit.api.Git;
59 import org.eclipse.jgit.api.errors.GitAPIException;
60 import org.eclipse.jgit.api.errors.NoFilepatternException;
61 import org.eclipse.jgit.attributes.Attribute.State;
62 import org.eclipse.jgit.dircache.DirCacheIterator;
63 import org.eclipse.jgit.errors.NoWorkTreeException;
64 import org.eclipse.jgit.junit.JGitTestUtil;
65 import org.eclipse.jgit.junit.RepositoryTestCase;
66 import org.eclipse.jgit.lib.FileMode;
67 import org.eclipse.jgit.lib.Repository;
68 import org.eclipse.jgit.treewalk.FileTreeIterator;
69 import org.eclipse.jgit.treewalk.TreeWalk;
70 import org.eclipse.jgit.treewalk.TreeWalk.OperationType;
71 import org.junit.After;
72 import org.junit.Before;
73 import org.junit.Test;
74
75
76
77
78
79
80 public class TreeWalkAttributeTest extends RepositoryTestCase {
81
82 private static final FileMode M = FileMode.MISSING;
83
84 private static final FileMode D = FileMode.TREE;
85
86 private static final FileMode F = FileMode.REGULAR_FILE;
87
88 private static Attribute EOL_CRLF = new Attribute("eol", "crlf");
89
90 private static Attribute EOL_LF = new Attribute("eol", "lf");
91
92 private static Attribute TEXT_SET = new Attribute("text", State.SET);
93
94 private static Attribute TEXT_UNSET = new Attribute("text", State.UNSET);
95
96 private static Attribute DELTA_UNSET = new Attribute("delta", State.UNSET);
97
98 private static Attribute DELTA_SET = new Attribute("delta", State.SET);
99
100 private static Attribute CUSTOM_GLOBAL = new Attribute("custom", "global");
101
102 private static Attribute CUSTOM_INFO = new Attribute("custom", "info");
103
104 private static Attribute CUSTOM_ROOT = new Attribute("custom", "root");
105
106 private static Attribute CUSTOM_PARENT = new Attribute("custom", "parent");
107
108 private static Attribute CUSTOM_CURRENT = new Attribute("custom", "current");
109
110 private static Attribute CUSTOM2_UNSET = new Attribute("custom2",
111 State.UNSET);
112
113 private static Attribute CUSTOM2_SET = new Attribute("custom2", State.SET);
114
115 private TreeWalk walk;
116
117 private TreeWalk ci_walk;
118
119 private Git git;
120
121 private File customAttributeFile;
122
123 @Override
124 @Before
125 public void setUp() throws Exception {
126 super.setUp();
127 git = new Git(db);
128 }
129
130 @Override
131 @After
132 public void tearDown() throws Exception {
133 super.tearDown();
134 if (customAttributeFile != null)
135 customAttributeFile.delete();
136 }
137
138
139
140
141
142
143
144
145
146
147
148
149
150 @Test
151 public void testCheckinCheckoutDifferences() throws IOException,
152 NoFilepatternException, GitAPIException {
153
154 writeGlobalAttributeFile("globalAttributesFile", "*.txt -custom2");
155 writeAttributesFile(".git/info/attributes", "*.txt eol=crlf");
156 writeAttributesFile(".gitattributes", "*.txt custom=root");
157 writeAttributesFile("level1/.gitattributes", "*.txt text");
158 writeAttributesFile("level1/level2/.gitattributes", "*.txt -delta");
159
160 writeTrashFile("l0.txt", "");
161
162 writeTrashFile("level1/l1.txt", "");
163
164 writeTrashFile("level1/level2/l2.txt", "");
165
166 git.add().addFilepattern(".").call();
167
168 beginWalk();
169
170
171 writeGlobalAttributeFile("globalAttributesFile", "*.txt custom2");
172 writeAttributesFile(".git/info/attributes", "*.txt eol=lf");
173 writeAttributesFile(".gitattributes", "*.txt custom=info");
174 writeAttributesFile("level1/.gitattributes", "*.txt -text");
175 writeAttributesFile("level1/level2/.gitattributes", "*.txt delta");
176
177 assertEntry(F, ".gitattributes");
178 assertEntry(F, "l0.txt", asSet(EOL_LF, CUSTOM_INFO, CUSTOM2_SET),
179 asSet(EOL_LF, CUSTOM_ROOT, CUSTOM2_SET));
180
181 assertEntry(D, "level1");
182 assertEntry(F, "level1/.gitattributes");
183 assertEntry(F, "level1/l1.txt",
184 asSet(EOL_LF, CUSTOM_INFO, CUSTOM2_SET, TEXT_UNSET),
185 asSet(EOL_LF, CUSTOM_ROOT, CUSTOM2_SET, TEXT_SET));
186
187 assertEntry(D, "level1/level2");
188 assertEntry(F, "level1/level2/.gitattributes");
189 assertEntry(F, "level1/level2/l2.txt",
190 asSet(EOL_LF, CUSTOM_INFO, CUSTOM2_SET, TEXT_UNSET, DELTA_SET),
191 asSet(EOL_LF, CUSTOM_ROOT, CUSTOM2_SET, TEXT_SET, DELTA_UNSET));
192
193 endWalk();
194 }
195
196
197
198
199
200
201
202
203
204 @Test
205 public void testIndexOnly() throws IOException, NoFilepatternException,
206 GitAPIException {
207 List<File> attrFiles = new ArrayList<>();
208 attrFiles.add(writeGlobalAttributeFile("globalAttributesFile",
209 "*.txt -custom2"));
210 attrFiles.add(writeAttributesFile(".git/info/attributes",
211 "*.txt eol=crlf"));
212 attrFiles
213 .add(writeAttributesFile(".gitattributes", "*.txt custom=root"));
214 attrFiles
215 .add(writeAttributesFile("level1/.gitattributes", "*.txt text"));
216 attrFiles.add(writeAttributesFile("level1/level2/.gitattributes",
217 "*.txt -delta"));
218
219 writeTrashFile("l0.txt", "");
220
221 writeTrashFile("level1/l1.txt", "");
222
223 writeTrashFile("level1/level2/l2.txt", "");
224
225 git.add().addFilepattern(".").call();
226
227
228 for (File attrFile : attrFiles)
229 attrFile.delete();
230
231 beginWalk();
232
233 assertEntry(M, ".gitattributes");
234 assertEntry(F, "l0.txt", asSet(CUSTOM_ROOT));
235
236 assertEntry(D, "level1");
237 assertEntry(M, "level1/.gitattributes");
238 assertEntry(F, "level1/l1.txt",
239
240 asSet(CUSTOM_ROOT, TEXT_SET));
241
242 assertEntry(D, "level1/level2");
243 assertEntry(M, "level1/level2/.gitattributes");
244 assertEntry(F, "level1/level2/l2.txt",
245
246 asSet(CUSTOM_ROOT, TEXT_SET, DELTA_UNSET));
247
248 endWalk();
249 }
250
251
252
253
254
255
256
257
258
259 @Test
260 public void testIndexOnly2()
261 throws IOException, NoFilepatternException, GitAPIException {
262 File l2 = writeTrashFile("level1/level2/l2.txt", "");
263 writeTrashFile("level1/level2/l1.txt", "");
264
265 git.add().addFilepattern(".").call();
266
267 writeAttributesFile(".gitattributes", "*.txt custom=root");
268 assertTrue(l2.delete());
269
270 beginWalk();
271
272 assertEntry(F, ".gitattributes");
273 assertEntry(D, "level1");
274 assertEntry(D, "level1/level2");
275 assertEntry(F, "level1/level2/l1.txt", asSet(CUSTOM_ROOT));
276 assertEntry(M, "level1/level2/l2.txt", asSet(CUSTOM_ROOT));
277
278 endWalk();
279 }
280
281
282
283
284
285
286
287
288
289
290
291 @Test
292 public void testRules() throws IOException, NoFilepatternException,
293 GitAPIException {
294 writeAttributesFile(".git/info/attributes", "windows* eol=crlf");
295
296 writeAttributesFile(".gitattributes", "*.txt eol=lf");
297 writeTrashFile("windows.file", "");
298 writeTrashFile("windows.txt", "");
299 writeTrashFile("readme.txt", "");
300
301 writeAttributesFile("src/config/.gitattributes", "*.txt -delta");
302 writeTrashFile("src/config/readme.txt", "");
303 writeTrashFile("src/config/windows.file", "");
304 writeTrashFile("src/config/windows.txt", "");
305
306 beginWalk();
307
308 git.add().addFilepattern(".").call();
309
310 assertEntry(F, ".gitattributes");
311 assertEntry(F, "readme.txt", asSet(EOL_LF));
312
313 assertEntry(D, "src");
314 assertEntry(D, "src/config");
315 assertEntry(F, "src/config/.gitattributes");
316 assertEntry(F, "src/config/readme.txt", asSet(DELTA_UNSET, EOL_LF));
317 assertEntry(F, "src/config/windows.file", asSet(EOL_CRLF));
318 assertEntry(F, "src/config/windows.txt", asSet(DELTA_UNSET, EOL_CRLF));
319
320 assertEntry(F, "windows.file", asSet(EOL_CRLF));
321 assertEntry(F, "windows.txt", asSet(EOL_CRLF));
322
323 endWalk();
324 }
325
326
327
328
329
330
331
332 @Test
333 public void testNoAttributes() throws IOException {
334 writeTrashFile("l0.txt", "");
335 writeTrashFile("level1/l1.txt", "");
336 writeTrashFile("level1/level2/l2.txt", "");
337
338 beginWalk();
339
340 assertEntry(F, "l0.txt");
341
342 assertEntry(D, "level1");
343 assertEntry(F, "level1/l1.txt");
344
345 assertEntry(D, "level1/level2");
346 assertEntry(F, "level1/level2/l2.txt");
347
348 endWalk();
349 }
350
351
352
353
354
355
356 @Test
357 public void testEmptyGitAttributeFile() throws IOException {
358 writeAttributesFile(".git/info/attributes", "");
359 writeTrashFile("l0.txt", "");
360 writeAttributesFile(".gitattributes", "");
361 writeTrashFile("level1/l1.txt", "");
362 writeTrashFile("level1/level2/l2.txt", "");
363
364 beginWalk();
365
366 assertEntry(F, ".gitattributes");
367 assertEntry(F, "l0.txt");
368
369 assertEntry(D, "level1");
370 assertEntry(F, "level1/l1.txt");
371
372 assertEntry(D, "level1/level2");
373 assertEntry(F, "level1/level2/l2.txt");
374
375 endWalk();
376 }
377
378 @Test
379 public void testNoMatchingAttributes() throws IOException {
380 writeAttributesFile(".git/info/attributes", "*.java delta");
381 writeAttributesFile(".gitattributes", "*.java -delta");
382 writeAttributesFile("levelA/.gitattributes", "*.java eol=lf");
383 writeAttributesFile("levelB/.gitattributes", "*.txt eol=lf");
384
385 writeTrashFile("levelA/lA.txt", "");
386
387 beginWalk();
388
389 assertEntry(F, ".gitattributes");
390
391 assertEntry(D, "levelA");
392 assertEntry(F, "levelA/.gitattributes");
393 assertEntry(F, "levelA/lA.txt");
394
395 assertEntry(D, "levelB");
396 assertEntry(F, "levelB/.gitattributes");
397
398 endWalk();
399 }
400
401
402
403
404
405
406 @Test
407 public void testPrecedenceInfo() throws IOException {
408 writeGlobalAttributeFile("globalAttributesFile", "*.txt custom=global");
409 writeAttributesFile(".git/info/attributes", "*.txt custom=info");
410 writeAttributesFile(".gitattributes", "*.txt custom=root");
411 writeAttributesFile("level1/.gitattributes", "*.txt custom=parent");
412 writeAttributesFile("level1/level2/.gitattributes",
413 "*.txt custom=current");
414
415 writeTrashFile("level1/level2/file.txt", "");
416
417 beginWalk();
418
419 assertEntry(F, ".gitattributes");
420
421 assertEntry(D, "level1");
422 assertEntry(F, "level1/.gitattributes");
423
424 assertEntry(D, "level1/level2");
425 assertEntry(F, "level1/level2/.gitattributes");
426 assertEntry(F, "level1/level2/file.txt", asSet(CUSTOM_INFO));
427
428 endWalk();
429 }
430
431
432
433
434
435
436
437 @Test
438 public void testPrecedenceCurrent() throws IOException {
439 writeGlobalAttributeFile("globalAttributesFile", "*.txt custom=global");
440 writeAttributesFile(".gitattributes", "*.txt custom=root");
441 writeAttributesFile("level1/.gitattributes", "*.txt custom=parent");
442 writeAttributesFile("level1/level2/.gitattributes",
443 "*.txt custom=current");
444
445 writeTrashFile("level1/level2/file.txt", "");
446
447 beginWalk();
448
449 assertEntry(F, ".gitattributes");
450
451 assertEntry(D, "level1");
452 assertEntry(F, "level1/.gitattributes");
453
454 assertEntry(D, "level1/level2");
455 assertEntry(F, "level1/level2/.gitattributes");
456 assertEntry(F, "level1/level2/file.txt", asSet(CUSTOM_CURRENT));
457
458 endWalk();
459 }
460
461
462
463
464
465
466 @Test
467 public void testPrecedenceParent() throws IOException {
468 writeGlobalAttributeFile("globalAttributesFile", "*.txt custom=global");
469 writeAttributesFile(".gitattributes", "*.txt custom=root");
470 writeAttributesFile("level1/.gitattributes", "*.txt custom=parent");
471
472 writeTrashFile("level1/level2/file.txt", "");
473
474 beginWalk();
475
476 assertEntry(F, ".gitattributes");
477
478 assertEntry(D, "level1");
479 assertEntry(F, "level1/.gitattributes");
480
481 assertEntry(D, "level1/level2");
482 assertEntry(F, "level1/level2/file.txt", asSet(CUSTOM_PARENT));
483
484 endWalk();
485 }
486
487
488
489
490
491
492 @Test
493 public void testPrecedenceRoot() throws IOException {
494 writeGlobalAttributeFile("globalAttributesFile", "*.txt custom=global");
495 writeAttributesFile(".gitattributes", "*.txt custom=root");
496
497 writeTrashFile("level1/level2/file.txt", "");
498
499 beginWalk();
500
501 assertEntry(F, ".gitattributes");
502
503 assertEntry(D, "level1");
504
505 assertEntry(D, "level1/level2");
506 assertEntry(F, "level1/level2/file.txt", asSet(CUSTOM_ROOT));
507
508 endWalk();
509 }
510
511
512
513
514
515
516 @Test
517 public void testPrecedenceGlobal() throws IOException {
518 writeGlobalAttributeFile("globalAttributesFile", "*.txt custom=global");
519
520 writeTrashFile("level1/level2/file.txt", "");
521
522 beginWalk();
523
524 assertEntry(D, "level1");
525
526 assertEntry(D, "level1/level2");
527 assertEntry(F, "level1/level2/file.txt", asSet(CUSTOM_GLOBAL));
528
529 endWalk();
530 }
531
532
533
534
535
536
537
538
539
540
541
542 @Test
543 public void testHierarchyBothIterator() throws IOException,
544 NoFilepatternException, GitAPIException {
545 writeAttributesFile(".git/info/attributes", "*.global eol=crlf");
546 writeAttributesFile(".gitattributes", "*.local eol=lf");
547 writeAttributesFile("level1/.gitattributes", "*.local text");
548 writeAttributesFile("level1/level2/.gitattributes", "*.local -text");
549
550 writeTrashFile("l0.global", "");
551 writeTrashFile("l0.local", "");
552
553 writeTrashFile("level1/l1.global", "");
554 writeTrashFile("level1/l1.local", "");
555
556 writeTrashFile("level1/level2/l2.global", "");
557 writeTrashFile("level1/level2/l2.local", "");
558
559 beginWalk();
560
561 git.add().addFilepattern(".").call();
562
563 assertEntry(F, ".gitattributes");
564 assertEntry(F, "l0.global", asSet(EOL_CRLF));
565 assertEntry(F, "l0.local", asSet(EOL_LF));
566
567 assertEntry(D, "level1");
568 assertEntry(F, "level1/.gitattributes");
569 assertEntry(F, "level1/l1.global", asSet(EOL_CRLF));
570 assertEntry(F, "level1/l1.local", asSet(EOL_LF, TEXT_SET));
571
572 assertEntry(D, "level1/level2");
573 assertEntry(F, "level1/level2/.gitattributes");
574 assertEntry(F, "level1/level2/l2.global", asSet(EOL_CRLF));
575 assertEntry(F, "level1/level2/l2.local", asSet(EOL_LF, TEXT_UNSET));
576
577 endWalk();
578
579 }
580
581
582
583
584
585
586
587
588
589
590
591 @Test
592 public void testHierarchyWorktreeOnly()
593 throws IOException, NoFilepatternException, GitAPIException {
594 writeAttributesFile(".git/info/attributes", "*.global eol=crlf");
595 writeAttributesFile(".gitattributes", "*.local eol=lf");
596 writeAttributesFile("level1/.gitattributes", "*.local text");
597 writeAttributesFile("level1/level2/.gitattributes", "*.local -text");
598
599 writeTrashFile("l0.global", "");
600 writeTrashFile("l0.local", "");
601
602 writeTrashFile("level1/l1.global", "");
603 writeTrashFile("level1/l1.local", "");
604
605 writeTrashFile("level1/level2/l2.global", "");
606 writeTrashFile("level1/level2/l2.local", "");
607
608 beginWalk();
609
610 assertEntry(F, ".gitattributes");
611 assertEntry(F, "l0.global", asSet(EOL_CRLF));
612 assertEntry(F, "l0.local", asSet(EOL_LF));
613
614 assertEntry(D, "level1");
615 assertEntry(F, "level1/.gitattributes");
616 assertEntry(F, "level1/l1.global", asSet(EOL_CRLF));
617 assertEntry(F, "level1/l1.local", asSet(EOL_LF, TEXT_SET));
618
619 assertEntry(D, "level1/level2");
620 assertEntry(F, "level1/level2/.gitattributes");
621 assertEntry(F, "level1/level2/l2.global", asSet(EOL_CRLF));
622 assertEntry(F, "level1/level2/l2.local", asSet(EOL_LF, TEXT_UNSET));
623
624 endWalk();
625
626 }
627
628
629
630
631
632
633
634 @Test
635 public void testAggregation() throws IOException {
636 writeGlobalAttributeFile("globalAttributesFile", "*.txt -custom2");
637 writeAttributesFile(".git/info/attributes", "*.txt eol=crlf");
638 writeAttributesFile(".gitattributes", "*.txt custom=root");
639 writeAttributesFile("level1/.gitattributes", "*.txt text");
640 writeAttributesFile("level1/level2/.gitattributes", "*.txt -delta");
641
642 writeTrashFile("l0.txt", "");
643
644 writeTrashFile("level1/l1.txt", "");
645
646 writeTrashFile("level1/level2/l2.txt", "");
647
648 beginWalk();
649
650 assertEntry(F, ".gitattributes");
651 assertEntry(F, "l0.txt", asSet(EOL_CRLF, CUSTOM_ROOT, CUSTOM2_UNSET));
652
653 assertEntry(D, "level1");
654 assertEntry(F, "level1/.gitattributes");
655 assertEntry(F, "level1/l1.txt",
656 asSet(EOL_CRLF, CUSTOM_ROOT, TEXT_SET, CUSTOM2_UNSET));
657
658 assertEntry(D, "level1/level2");
659 assertEntry(F, "level1/level2/.gitattributes");
660 assertEntry(
661 F,
662 "level1/level2/l2.txt",
663 asSet(EOL_CRLF, CUSTOM_ROOT, TEXT_SET, DELTA_UNSET,
664 CUSTOM2_UNSET));
665
666 endWalk();
667
668 }
669
670
671
672
673
674
675
676 @Test
677 public void testOverriding() throws IOException {
678 writeAttributesFile(".git/info/attributes",
679
680 "*.txt custom=current",
681 "*.txt custom=parent",
682 "*.txt custom=root",
683 "*.txt custom=info",
684
685 "*.txt delta",
686 "*.txt -delta",
687
688 "*.txt eol=lf",
689 "*.txt eol=crlf",
690
691 "*.txt text",
692 "*.txt -text");
693
694 writeTrashFile("l0.txt", "");
695 beginWalk();
696
697 assertEntry(F, "l0.txt",
698 asSet(TEXT_UNSET, EOL_CRLF, DELTA_UNSET, CUSTOM_INFO));
699
700 endWalk();
701 }
702
703
704
705
706
707
708
709 @Test
710 public void testOverriding2() throws IOException {
711 writeAttributesFile(".git/info/attributes",
712 "*.txt custom=current custom=parent custom=root custom=info",
713 "*.txt delta -delta",
714 "*.txt eol=lf eol=crlf",
715 "*.txt text -text");
716 writeTrashFile("l0.txt", "");
717 beginWalk();
718
719 assertEntry(F, "l0.txt",
720 asSet(TEXT_UNSET, EOL_CRLF, DELTA_UNSET, CUSTOM_INFO));
721
722 endWalk();
723 }
724
725 @Test
726 public void testRulesInherited() throws Exception {
727 writeAttributesFile(".gitattributes", "**/*.txt eol=lf");
728 writeTrashFile("src/config/readme.txt", "");
729 writeTrashFile("src/config/windows.file", "");
730
731 beginWalk();
732
733 assertEntry(F, ".gitattributes");
734 assertEntry(D, "src");
735 assertEntry(D, "src/config");
736
737 assertEntry(F, "src/config/readme.txt", asSet(EOL_LF));
738 assertEntry(F, "src/config/windows.file",
739 Collections.<Attribute> emptySet());
740
741 endWalk();
742 }
743
744 private void beginWalk() throws NoWorkTreeException, IOException {
745 walk = new TreeWalk(db);
746 walk.addTree(new FileTreeIterator(db));
747 walk.addTree(new DirCacheIterator(db.readDirCache()));
748
749 ci_walk = new TreeWalk(db);
750 ci_walk.setOperationType(OperationType.CHECKIN_OP);
751 ci_walk.addTree(new FileTreeIterator(db));
752 ci_walk.addTree(new DirCacheIterator(db.readDirCache()));
753 }
754
755
756
757
758
759
760
761
762
763
764 private void assertEntry(FileMode type, String pathName,
765 Set<Attribute> forBothOperaiton) throws IOException {
766 assertEntry(type, pathName, forBothOperaiton, forBothOperaiton);
767 }
768
769
770
771
772
773
774
775
776 private void assertEntry(FileMode type, String pathName) throws IOException {
777 assertEntry(type, pathName, Collections.<Attribute> emptySet(),
778 Collections.<Attribute> emptySet());
779 }
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796 private void assertEntry(FileMode type, String pathName,
797 Set<Attribute> checkinAttributes, Set<Attribute> checkoutAttributes)
798 throws IOException {
799 assertTrue("walk has entry", walk.next());
800 assertTrue("walk has entry", ci_walk.next());
801 assertEquals(pathName, walk.getPathString());
802 assertEquals(type, walk.getFileMode(0));
803
804 assertEquals(checkinAttributes,
805 asSet(ci_walk.getAttributes().getAll()));
806 assertEquals(checkoutAttributes,
807 asSet(walk.getAttributes().getAll()));
808
809 if (D.equals(type)) {
810 walk.enterSubtree();
811 ci_walk.enterSubtree();
812 }
813 }
814
815 private static Set<Attribute> asSet(Collection<Attribute> attributes) {
816 Set<Attribute> ret = new HashSet<>();
817 for (Attribute a : attributes) {
818 ret.add(a);
819 }
820 return (ret);
821 }
822
823 private File writeAttributesFile(String name, String... rules)
824 throws IOException {
825 StringBuilder data = new StringBuilder();
826 for (String line : rules)
827 data.append(line + "\n");
828 return writeTrashFile(name, data.toString());
829 }
830
831
832
833
834
835
836
837
838
839
840 private File writeGlobalAttributeFile(String fileName, String... attributes)
841 throws IOException {
842 customAttributeFile = File.createTempFile("tmp_", fileName, null);
843 customAttributeFile.deleteOnExit();
844 StringBuilder attributesFileContent = new StringBuilder();
845 for (String attr : attributes) {
846 attributesFileContent.append(attr).append("\n");
847 }
848 JGitTestUtil.write(customAttributeFile,
849 attributesFileContent.toString());
850 db.getConfig().setString("core", null, "attributesfile",
851 customAttributeFile.getAbsolutePath());
852 return customAttributeFile;
853 }
854
855 static Set<Attribute> asSet(Attribute... attrs) {
856 HashSet<Attribute> result = new HashSet<>();
857 for (Attribute attr : attrs)
858 result.add(attr);
859 return result;
860 }
861
862 private void endWalk() throws IOException {
863 assertFalse("Not all files tested", walk.next());
864 assertFalse("Not all files tested", ci_walk.next());
865 }
866 }