1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.api;
11
12 import static java.nio.charset.StandardCharsets.UTF_8;
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertFalse;
15 import static org.junit.Assert.assertTrue;
16
17 import java.io.File;
18 import java.io.IOException;
19
20 import org.eclipse.jgit.api.ResetCommand.ResetType;
21 import org.eclipse.jgit.api.errors.CheckoutConflictException;
22 import org.eclipse.jgit.api.errors.GitAPIException;
23 import org.eclipse.jgit.api.errors.NoFilepatternException;
24 import org.eclipse.jgit.attributes.Attribute;
25 import org.eclipse.jgit.dircache.DirCache;
26 import org.eclipse.jgit.dircache.DirCacheEditor;
27 import org.eclipse.jgit.dircache.DirCacheEntry;
28 import org.eclipse.jgit.dircache.DirCacheIterator;
29 import org.eclipse.jgit.errors.RevisionSyntaxException;
30 import org.eclipse.jgit.junit.RepositoryTestCase;
31 import org.eclipse.jgit.lib.ConfigConstants;
32 import org.eclipse.jgit.lib.Constants;
33 import org.eclipse.jgit.lib.CoreConfig.AutoCRLF;
34 import org.eclipse.jgit.lib.CoreConfig.EOL;
35 import org.eclipse.jgit.lib.FileMode;
36 import org.eclipse.jgit.lib.ObjectLoader;
37 import org.eclipse.jgit.revwalk.RevCommit;
38 import org.eclipse.jgit.storage.file.FileBasedConfig;
39 import org.eclipse.jgit.treewalk.FileTreeIterator;
40 import org.eclipse.jgit.treewalk.TreeWalk;
41 import org.eclipse.jgit.util.FS;
42 import org.eclipse.jgit.util.IO;
43 import org.junit.Assert;
44 import org.junit.Test;
45 import org.junit.experimental.theories.DataPoint;
46 import org.junit.experimental.theories.Theories;
47 import org.junit.runner.RunWith;
48
49
50
51
52
53
54 @RunWith(Theories.class)
55 public class EolRepositoryTest extends RepositoryTestCase {
56 private static final FileMode D = FileMode.TREE;
57
58 private static final FileMode F = FileMode.REGULAR_FILE;
59
60 @DataPoint
61 public static boolean doSmudgeEntries = true;
62
63 @DataPoint
64 public static boolean dontSmudgeEntries = false;
65
66 private boolean smudge;
67
68 @DataPoint
69 public static String smallContents[] = {
70 generateTestData(3, 1, true, false),
71 generateTestData(3, 1, false, true),
72 generateTestData(3, 1, true, true) };
73
74 @DataPoint
75 public static String hugeContents[] = {
76 generateTestData(1000000, 17, true, false),
77 generateTestData(1000000, 17, false, true),
78 generateTestData(1000000, 17, true, true) };
79
80 static String generateTestData(int size, int lineSize, boolean withCRLF,
81 boolean withLF) {
82 StringBuilder sb = new StringBuilder();
83 for (int i = 0; i < size; i++) {
84 if (i > 0 && i % lineSize == 0) {
85
86 if (withCRLF && withLF) {
87
88 if (i % 2 == 0)
89 sb.append("\r\n");
90 else
91 sb.append("\n");
92 } else if (withCRLF) {
93 sb.append("\r\n");
94 } else if (withLF) {
95 sb.append("\n");
96 }
97 }
98 sb.append("A");
99 }
100 return sb.toString();
101 }
102
103 public EolRepositoryTest(String[] testContent, boolean smudgeEntries) {
104 CONTENT_CRLF = testContent[0];
105 CONTENT_LF = testContent[1];
106 CONTENT_MIXED = testContent[2];
107 this.smudge = smudgeEntries;
108 }
109
110 protected String CONTENT_CRLF;
111
112 protected String CONTENT_LF;
113
114 protected String CONTENT_MIXED;
115
116
117 private File dotGitattributes;
118
119
120 private File fileCRLF;
121
122
123 private File fileLF;
124
125
126 private File fileMixed;
127
128
129 private static class ActualEntry {
130 private String attrs;
131
132 private String file;
133
134 private String index;
135
136 private int indexContentLength;
137 }
138
139 private ActualEntry entryCRLF = new ActualEntry();
140
141 private ActualEntry entryLF = new ActualEntry();
142
143 private ActualEntry entryMixed = new ActualEntry();
144
145 private DirCache dirCache;
146
147 private boolean isDefaultCrLf() {
148 String eol = mockSystemReader.getProperty("line.separator");
149 return "\r\n".equals(eol);
150 }
151
152 @Test
153 public void testDefaultSetup() throws Exception {
154
155 setupGitAndDoHardReset(null, null, null, null, "* text=auto");
156 collectRepositoryState();
157 assertEquals("text=auto", entryCRLF.attrs);
158
159 String expected = isDefaultCrLf() ? CONTENT_CRLF : CONTENT_LF;
160 checkEntryContent(entryCRLF, expected, CONTENT_LF);
161 checkEntryContent(entryLF, expected, CONTENT_LF);
162 checkEntryContent(entryMixed, expected, CONTENT_LF);
163 }
164
165 public void checkEntryContent(ActualEntry entry, String fileContent,
166 String indexContent) {
167 assertEquals(fileContent, entry.file);
168 assertEquals(indexContent, entry.index);
169 if (entry.indexContentLength != 0) {
170 assertEquals(fileContent.length(), entry.indexContentLength);
171 }
172 }
173
174 @Test
175 public void test_ConfigAutoCRLF_false() throws Exception {
176
177 setupGitAndDoHardReset(AutoCRLF.FALSE, null, null, null, "* text=auto");
178 collectRepositoryState();
179 assertEquals("text=auto", entryCRLF.attrs);
180
181 String expected = isDefaultCrLf() ? CONTENT_CRLF : CONTENT_LF;
182 checkEntryContent(entryCRLF, expected, CONTENT_LF);
183 checkEntryContent(entryLF, expected, CONTENT_LF);
184 checkEntryContent(entryMixed, expected, CONTENT_LF);
185 }
186
187 @Test
188 public void test_ConfigAutoCRLF_true() throws Exception {
189
190 setupGitAndDoHardReset(AutoCRLF.TRUE, null, null, null, "* text=auto");
191 collectRepositoryState();
192 assertEquals("text=auto", entryCRLF.attrs);
193 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
194 checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
195 checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
196 }
197
198 @Test
199 public void test_ConfigAutoCRLF_input() throws Exception {
200
201 setupGitAndDoHardReset(AutoCRLF.INPUT, null, null, null, "* text=auto");
202 collectRepositoryState();
203 assertEquals("text=auto", entryCRLF.attrs);
204 checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
205 checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
206 checkEntryContent(entryMixed, CONTENT_LF, CONTENT_LF);
207 }
208
209 @Test
210 public void test_ConfigEOL_lf() throws Exception {
211
212 setupGitAndDoHardReset(null, EOL.LF, "*.txt text", null, null);
213 collectRepositoryState();
214 assertEquals("text", entryCRLF.attrs);
215 checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
216 checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
217 checkEntryContent(entryMixed, CONTENT_LF, CONTENT_LF);
218 }
219
220 @Test
221 public void test_ConfigEOL_crlf() throws Exception {
222
223 setupGitAndDoHardReset(null, EOL.CRLF, "*.txt text", null, null);
224 collectRepositoryState();
225 assertEquals("text", entryCRLF.attrs);
226 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
227 checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
228 checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
229 }
230
231 @Test
232 public void test_ConfigEOL_native_windows() throws Exception {
233 mockSystemReader.setWindows();
234
235 setupGitAndDoHardReset(null, EOL.NATIVE, "*.txt text", null, null);
236 collectRepositoryState();
237 assertEquals("text", entryCRLF.attrs);
238 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
239 checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
240 }
241
242 @Test
243 public void test_ConfigEOL_native_xnix() throws Exception {
244 mockSystemReader.setUnix();
245
246 setupGitAndDoHardReset(null, EOL.NATIVE, "*.txt text", null, null);
247 collectRepositoryState();
248 assertEquals("text", entryCRLF.attrs);
249 checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
250 checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
251 }
252
253 @Test
254 public void test_ConfigAutoCRLF_false_ConfigEOL_lf() throws Exception {
255
256 setupGitAndDoHardReset(AutoCRLF.FALSE, EOL.LF, "*.txt text", null, null);
257 collectRepositoryState();
258 assertEquals("text", entryCRLF.attrs);
259 checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
260 checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
261 checkEntryContent(entryMixed, CONTENT_LF, CONTENT_LF);
262 }
263
264 @Test
265 public void test_ConfigAutoCRLF_false_ConfigEOL_native() throws Exception {
266
267 setupGitAndDoHardReset(AutoCRLF.FALSE, EOL.NATIVE, "*.txt text", null, null);
268 collectRepositoryState();
269 assertEquals("text", entryCRLF.attrs);
270 String expected = isDefaultCrLf() ? CONTENT_CRLF : CONTENT_LF;
271 checkEntryContent(entryCRLF, expected, CONTENT_LF);
272 checkEntryContent(entryLF, expected, CONTENT_LF);
273 checkEntryContent(entryMixed, expected, CONTENT_LF);
274 }
275
276 @Test
277 public void test_ConfigAutoCRLF_true_ConfigEOL_lf() throws Exception {
278
279 setupGitAndDoHardReset(AutoCRLF.TRUE, EOL.LF, "*.txt text", null, null);
280 collectRepositoryState();
281 assertEquals("text", entryCRLF.attrs);
282 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
283 checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
284 checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
285 }
286
287 @Test
288 public void test_switchToBranchWithTextAttributes()
289 throws Exception {
290 Git git = Git.wrap(db);
291
292
293 setupGitAndDoHardReset(AutoCRLF.FALSE, EOL.CRLF, null, null,
294 "file1.txt text\nfile2.txt text\nfile3.txt text");
295 collectRepositoryState();
296 assertEquals("text", entryCRLF.attrs);
297 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
298 checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
299 checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
300
301
302 dotGitattributes = createAndAddFile(git, Constants.DOT_GIT_ATTRIBUTES,
303 "file1.txt binary\nfile2.txt text\nfile3.txt text");
304 gitCommit(git, "switchedToBinaryFor1");
305 recreateWorktree(git);
306 collectRepositoryState();
307 assertEquals("binary -diff -merge -text", entryCRLF.attrs);
308 checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
309 assertEquals("text", entryLF.attrs);
310 checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
311 assertEquals("text", entryMixed.attrs);
312 checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
313
314
315 gitCheckout(git, "HEAD^");
316 recreateWorktree(git);
317 collectRepositoryState();
318 assertEquals("text", entryCRLF.attrs);
319 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
320 checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
321 checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
322 }
323
324 @Test
325 public void test_switchToBranchWithBinaryAttributes() throws Exception {
326 Git git = Git.wrap(db);
327
328
329 setupGitAndDoHardReset(AutoCRLF.FALSE, EOL.LF, null, null,
330 "file1.txt binary\nfile2.txt binary\nfile3.txt binary");
331 collectRepositoryState();
332 assertEquals("binary -diff -merge -text", entryCRLF.attrs);
333 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_CRLF);
334 checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
335 checkEntryContent(entryMixed, CONTENT_MIXED, CONTENT_MIXED);
336
337
338 dotGitattributes = createAndAddFile(git, Constants.DOT_GIT_ATTRIBUTES,
339 "file1.txt text\nfile2.txt binary\nfile3.txt binary");
340 gitCommit(git, "switchedToTextFor1");
341 recreateWorktree(git);
342 collectRepositoryState();
343 assertEquals("text", entryCRLF.attrs);
344 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
345 assertEquals("binary -diff -merge -text", entryLF.attrs);
346 checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
347 assertEquals("binary -diff -merge -text", entryMixed.attrs);
348 checkEntryContent(entryMixed, CONTENT_MIXED, CONTENT_MIXED);
349
350
351 gitCheckout(git, "HEAD^");
352 recreateWorktree(git);
353 collectRepositoryState();
354 assertEquals("binary -diff -merge -text", entryCRLF.attrs);
355 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_CRLF);
356 checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
357 checkEntryContent(entryMixed, CONTENT_MIXED, CONTENT_MIXED);
358 }
359
360 @Test
361 public void test_ConfigAutoCRLF_input_ConfigEOL_lf() throws Exception {
362
363 setupGitAndDoHardReset(AutoCRLF.INPUT, EOL.LF, "*.txt text", null, null);
364 collectRepositoryState();
365 assertEquals("text", entryCRLF.attrs);
366 checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
367 checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
368 checkEntryContent(entryMixed, CONTENT_LF, CONTENT_LF);
369 }
370
371 @Test
372 public void test_ConfigAutoCRLF_true_GlobalEOL_lf() throws Exception {
373 setupGitAndDoHardReset(AutoCRLF.TRUE, EOL.LF, "*.txt eol=lf", null, null);
374 collectRepositoryState();
375 assertEquals("eol=lf", entryCRLF.attrs);
376 checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
377 checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
378 checkEntryContent(entryMixed, CONTENT_LF, CONTENT_LF);
379 }
380
381 @Test
382 public void test_ConfigAutoCRLF_false_GlobalEOL_lf() throws Exception {
383 setupGitAndDoHardReset(AutoCRLF.FALSE, EOL.LF, "*.txt eol=lf", null, null);
384 collectRepositoryState();
385 assertEquals("eol=lf", entryCRLF.attrs);
386 checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
387 checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
388 checkEntryContent(entryMixed, CONTENT_LF, CONTENT_LF);
389 }
390
391 @Test
392 public void test_ConfigAutoCRLF_input_GlobalEOL_lf() throws Exception {
393 setupGitAndDoHardReset(AutoCRLF.INPUT, EOL.LF, "*.txt eol=lf", null, null);
394 collectRepositoryState();
395 assertEquals("eol=lf", entryCRLF.attrs);
396 checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
397 checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
398 checkEntryContent(entryMixed, CONTENT_LF, CONTENT_LF);
399 }
400
401 @Test
402 public void test_ConfigAutoCRLF_true_GlobalEOL_crlf() throws Exception {
403 setupGitAndDoHardReset(AutoCRLF.TRUE, EOL.LF, "*.txt eol=crlf", null, null);
404 collectRepositoryState();
405 assertEquals("eol=crlf", entryCRLF.attrs);
406 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
407 checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
408 checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
409 }
410
411 @Test
412 public void test_ConfigAutoCRLF_false_GlobalEOL_crlf() throws Exception {
413 setupGitAndDoHardReset(AutoCRLF.FALSE, EOL.LF, "*.txt eol=crlf", null, null);
414 collectRepositoryState();
415 assertEquals("eol=crlf", entryCRLF.attrs);
416 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
417 checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
418 checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
419 }
420
421 @Test
422 public void test_ConfigAutoCRLF_input_GlobalEOL_crlf() throws Exception {
423 setupGitAndDoHardReset(AutoCRLF.INPUT, EOL.LF, "*.txt eol=crlf", null, null);
424 collectRepositoryState();
425 assertEquals("eol=crlf", entryCRLF.attrs);
426 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
427 checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
428 checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
429 }
430
431 @Test
432 public void test_ConfigAutoCRLF_true_GlobalEOL_lf_InfoEOL_crlf()
433 throws Exception {
434 setupGitAndDoHardReset(AutoCRLF.TRUE, null, "*.txt eol=lf", "*.txt eol=crlf", null);
435
436 collectRepositoryState();
437 assertEquals("eol=crlf", entryCRLF.attrs);
438 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
439 checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
440 checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
441 }
442
443 @Test
444 public void test_ConfigAutoCRLF_false_GlobalEOL_crlf_InfoEOL_lf()
445 throws Exception {
446 setupGitAndDoHardReset(AutoCRLF.FALSE, null, "*.txt eol=crlf", "*.txt eol=lf", null);
447
448 collectRepositoryState();
449 assertEquals("eol=lf", entryCRLF.attrs);
450 checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
451 checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
452 checkEntryContent(entryMixed, CONTENT_LF, CONTENT_LF);
453 }
454
455 @Test
456 public void test_GlobalEOL_lf_RootEOL_crlf() throws Exception {
457 setupGitAndDoHardReset(null, null, "*.txt eol=lf", null, "*.txt eol=crlf");
458
459 collectRepositoryState();
460 assertEquals("eol=crlf", entryCRLF.attrs);
461 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
462 checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
463 checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
464 }
465
466 @Test
467 public void test_GlobalEOL_lf_InfoEOL_crlf_RootEOL_lf() throws Exception {
468 setupGitAndDoHardReset(null, null, "*.txt eol=lf", "*.txt eol=crlf", "*.txt eol=lf");
469
470 collectRepositoryState();
471 assertEquals("eol=crlf", entryCRLF.attrs);
472 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
473 checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
474 checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
475 }
476
477 @Test
478 public void test_GlobalEOL_lf_InfoEOL_crlf_RootEOL_unspec()
479 throws Exception {
480 setupGitAndDoHardReset(null, null, "*.txt eol=lf", "*.txt eol=crlf",
481 "*.txt text !eol");
482
483 collectRepositoryState();
484 assertEquals("eol=crlf text", entryCRLF.attrs);
485 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
486 checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
487 checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
488 }
489
490 @Test
491 public void test_GlobalEOL_lf_InfoEOL_unspec_RootEOL_crlf()
492 throws Exception {
493 setupGitAndDoHardReset(null, null, "*.txt eol=lf", "*.txt !eol",
494 "*.txt text eol=crlf");
495
496 collectRepositoryState();
497 assertEquals("text", entryCRLF.attrs);
498
499
500 String expected = isDefaultCrLf() ? CONTENT_CRLF : CONTENT_LF;
501 checkEntryContent(entryCRLF, expected, CONTENT_LF);
502 checkEntryContent(entryLF, expected, CONTENT_LF);
503 checkEntryContent(entryMixed, expected, CONTENT_LF);
504 }
505
506 @Test
507 public void testBinary1() throws Exception {
508 setupGitAndDoHardReset(AutoCRLF.TRUE, EOL.CRLF, "*.txt text", "*.txt binary",
509 "*.txt eol=crlf");
510
511 collectRepositoryState();
512 assertEquals("binary -diff -merge -text eol=crlf", entryCRLF.attrs);
513 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_CRLF);
514 checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
515 checkEntryContent(entryMixed, CONTENT_MIXED, CONTENT_MIXED);
516 }
517
518 @Test
519 public void testBinary2() throws Exception {
520 setupGitAndDoHardReset(AutoCRLF.TRUE, EOL.CRLF, "*.txt text eol=crlf", null,
521 "*.txt binary");
522
523 collectRepositoryState();
524 assertEquals("binary -diff -merge -text eol=crlf", entryCRLF.attrs);
525 checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_CRLF);
526 checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
527 checkEntryContent(entryMixed, CONTENT_MIXED, CONTENT_MIXED);
528 }
529
530
531
532
533
534
535
536
537
538
539
540 private void setupGitAndDoHardReset(AutoCRLF autoCRLF, EOL eol,
541 String globalAttributesContent, String infoAttributesContent,
542 String workDirRootAttributesContent) throws Exception {
543 Git git = new Git(db);
544 FileBasedConfig config = db.getConfig();
545 if (autoCRLF != null) {
546 config.setEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
547 ConfigConstants.CONFIG_KEY_AUTOCRLF, autoCRLF);
548 }
549 if (eol != null) {
550 config.setEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
551 ConfigConstants.CONFIG_KEY_EOL, eol);
552 }
553 if (globalAttributesContent != null) {
554 File f = new File(db.getDirectory(), "global/attrs");
555 write(f, globalAttributesContent);
556 config.setString(ConfigConstants.CONFIG_CORE_SECTION, null,
557 ConfigConstants.CONFIG_KEY_ATTRIBUTESFILE,
558 f.getAbsolutePath());
559
560 }
561 if (infoAttributesContent != null) {
562 File f = new File(db.getDirectory(), Constants.INFO_ATTRIBUTES);
563 write(f, infoAttributesContent);
564 }
565 config.save();
566
567 if (workDirRootAttributesContent != null) {
568 dotGitattributes = createAndAddFile(git,
569 Constants.DOT_GIT_ATTRIBUTES, workDirRootAttributesContent);
570 } else {
571 dotGitattributes = null;
572 }
573
574 fileCRLF = createAndAddFile(git, "file1.txt", "a");
575
576 fileLF = createAndAddFile(git, "file2.txt", "a");
577
578 fileMixed = createAndAddFile(git, "file3.txt", "a");
579
580 RevCommit c = gitCommit(git, "create files");
581
582 fileCRLF = createAndAddFile(git, "file1.txt", CONTENT_CRLF);
583
584 fileLF = createAndAddFile(git, "file2.txt", CONTENT_LF);
585
586 fileMixed = createAndAddFile(git, "file3.txt", CONTENT_MIXED);
587
588 gitCommit(git, "addFiles");
589
590 recreateWorktree(git);
591
592 if (smudge) {
593 DirCache dc = DirCache.lock(git.getRepository().getIndexFile(),
594 FS.detect());
595 DirCacheEditor editor = dc.editor();
596 for (int i = 0; i < dc.getEntryCount(); i++) {
597 editor.add(new DirCacheEditor.PathEdit(
598 dc.getEntry(i).getPathString()) {
599 @Override
600 public void apply(DirCacheEntry ent) {
601 ent.smudgeRacilyClean();
602 }
603 });
604 }
605 editor.commit();
606 }
607
608
609
610 git.checkout().setName(c.getName()).call();
611 git.checkout().setName("master").call();
612 }
613
614 private void recreateWorktree(Git git)
615 throws GitAPIException, CheckoutConflictException,
616 InterruptedException, IOException, NoFilepatternException {
617
618 for (File f : new File[] { dotGitattributes, fileCRLF, fileLF, fileMixed }) {
619 if (f == null)
620 continue;
621 f.delete();
622 Assert.assertFalse(f.exists());
623 }
624 gitResetHard(git);
625 fsTick(db.getIndexFile());
626 gitAdd(git, ".");
627 }
628
629 protected RevCommit gitCommit(Git git, String msg) throws GitAPIException {
630 return git.commit().setMessage(msg).call();
631 }
632
633 protected void gitAdd(Git git, String path) throws GitAPIException {
634 git.add().addFilepattern(path).call();
635 }
636
637 protected void gitResetHard(Git git) throws GitAPIException {
638 git.reset().setMode(ResetType.HARD).call();
639 }
640
641 protected void gitCheckout(Git git, String revstr)
642 throws GitAPIException, RevisionSyntaxException, IOException {
643 git.checkout().setName(db.resolve(revstr).getName()).call();
644 }
645
646
647 private File createAndAddFile(Git git, String path, String content)
648 throws Exception {
649 File f;
650 int pos = path.lastIndexOf('/');
651 if (pos < 0) {
652 f = writeTrashFile(path, content);
653 } else {
654 f = writeTrashFile(path.substring(0, pos), path.substring(pos + 1),
655 content);
656 }
657 gitAdd(git, path);
658 Assert.assertTrue(f.exists());
659 return f;
660 }
661
662 private void collectRepositoryState() throws Exception {
663 dirCache = db.readDirCache();
664 try (TreeWalk walk = new TreeWalk(db)) {
665 walk.addTree(new FileTreeIterator(db));
666 walk.addTree(new DirCacheIterator(db.readDirCache()));
667 if (dotGitattributes != null) {
668 collectEntryContentAndAttributes(walk, F, ".gitattributes",
669 null);
670 }
671 collectEntryContentAndAttributes(walk, F, fileCRLF.getName(),
672 entryCRLF);
673 collectEntryContentAndAttributes(walk, F, fileLF.getName(),
674 entryLF);
675 collectEntryContentAndAttributes(walk, F, fileMixed.getName(),
676 entryMixed);
677 assertFalse("Not all files tested", walk.next());
678 }
679 }
680
681 private void collectEntryContentAndAttributes(TreeWalk walk, FileMode type,
682 String pathName,
683 ActualEntry e) throws IOException {
684 assertTrue("walk has entry", walk.next());
685
686 assertEquals(pathName, walk.getPathString());
687 assertEquals(type, walk.getFileMode(0));
688
689 if (e != null) {
690 e.attrs = "";
691 for (Attribute a : walk.getAttributes().getAll()) {
692 e.attrs += " " + a.toString();
693 }
694 e.attrs = e.attrs.trim();
695 e.file = new String(
696 IO.readFully(new File(db.getWorkTree(), pathName)), UTF_8);
697 DirCacheEntry dce = dirCache.getEntry(pathName);
698 ObjectLoader open = walk.getObjectReader().open(dce.getObjectId());
699 e.index = new String(open.getBytes(), UTF_8);
700 e.indexContentLength = dce.getLength();
701 }
702
703 if (D.equals(type))
704 walk.enterSubtree();
705 }
706 }