/*
 * Copyright (C) 2015, 2022 Ivan Motsch <ivan.motsch@bsiag.com> and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
package org.eclipse.jgit.api;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.IOException;

import org.eclipse.jgit.api.ResetCommand.ResetType;
import org.eclipse.jgit.api.errors.CheckoutConflictException;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.NoFilepatternException;
import org.eclipse.jgit.attributes.Attribute;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheEditor;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.dircache.DirCacheIterator;
import org.eclipse.jgit.errors.RevisionSyntaxException;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.CoreConfig.AutoCRLF;
import org.eclipse.jgit.lib.CoreConfig.EOL;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.treewalk.FileTreeIterator;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.IO;
import org.junit.Assert;
import org.junit.Test;
import org.junit.experimental.theories.DataPoint;
import org.junit.experimental.theories.Theories;
import org.junit.runner.RunWith;

/**
 * Unit tests for end-of-line conversion and settings using core.autocrlf, *
 * core.eol and the .gitattributes eol, text, binary (macro for -diff -merge
 * -text)
 */
@RunWith(Theories.class)
public class EolRepositoryTest extends RepositoryTestCase {
	private static final FileMode D = FileMode.TREE;

	private static final FileMode F = FileMode.REGULAR_FILE;

	@DataPoint
	public static boolean doSmudgeEntries = true;

	@DataPoint
	public static boolean dontSmudgeEntries = false;

	private boolean smudge;

	@DataPoint
	public static String smallContents[] = {
			generateTestData(3, 1, true, false),
			generateTestData(3, 1, false, true),
			generateTestData(3, 1, true, true) };

	@DataPoint
	public static String hugeContents[] = {
			generateTestData(1000000, 17, true, false),
			generateTestData(1000000, 17, false, true),
			generateTestData(1000000, 17, true, true) };

	static String generateTestData(int size, int lineSize, boolean withCRLF,
			boolean withLF) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < size; i++) {
			if (i > 0 && i % lineSize == 0) {
				// newline
				if (withCRLF && withLF) {
					// mixed
					if (i % 2 == 0)
						sb.append("\r\n");
					else
						sb.append("\n");
				} else if (withCRLF) {
					sb.append("\r\n");
				} else if (withLF) {
					sb.append("\n");
				}
			}
			sb.append("A");
		}
		return sb.toString();
	}

	public EolRepositoryTest(String[] testContent, boolean smudgeEntries) {
		CONTENT_CRLF = testContent[0];
		CONTENT_LF = testContent[1];
		CONTENT_MIXED = testContent[2];
		this.smudge = smudgeEntries;
	}

	protected String CONTENT_CRLF;

	protected String CONTENT_LF;

	protected String CONTENT_MIXED;

	/** work tree root .gitattributes */
	private File dotGitattributes;

	/** file containing CRLF */
	private File fileCRLF;

	/** file containing LF */
	private File fileLF;

	/** file containing mixed CRLF and LF */
	private File fileMixed;

	/** this values are set in {@link #collectRepositoryState()} */
	private static class ActualEntry {
		private String attrs;

		private String file;

		private String index;

		private int indexContentLength;
	}

	private ActualEntry entryCRLF = new ActualEntry();

	private ActualEntry entryLF = new ActualEntry();

	private ActualEntry entryMixed = new ActualEntry();

	private DirCache dirCache;

	private boolean isDefaultCrLf() {
		String eol = mockSystemReader.getProperty("line.separator");
		return "\r\n".equals(eol);
	}

	@Test
	public void testDefaultSetup() throws Exception {
		// for EOL to work, the text attribute must be set
		setupGitAndDoHardReset(null, null, null, null, "* text=auto");
		collectRepositoryState();
		assertEquals("text=auto", entryCRLF.attrs);
		// eol=native is the default!
		String expected = isDefaultCrLf() ? CONTENT_CRLF : CONTENT_LF;
		checkEntryContent(entryCRLF, expected, CONTENT_LF);
		checkEntryContent(entryLF, expected, CONTENT_LF);
		checkEntryContent(entryMixed, expected, CONTENT_LF);
	}

	public void checkEntryContent(ActualEntry entry, String fileContent,
			String indexContent) {
		assertEquals(fileContent, entry.file);
		assertEquals(indexContent, entry.index);
		if (entry.indexContentLength != 0) {
			assertEquals(fileContent.length(), entry.indexContentLength);
		}
	}

	@Test
	public void test_ConfigAutoCRLF_false() throws Exception {
		// for EOL to work, the text attribute must be set
		setupGitAndDoHardReset(AutoCRLF.FALSE, null, null, null, "* text=auto");
		collectRepositoryState();
		assertEquals("text=auto", entryCRLF.attrs);
		// eol=native is the default!
		String expected = isDefaultCrLf() ? CONTENT_CRLF : CONTENT_LF;
		checkEntryContent(entryCRLF, expected, CONTENT_LF);
		checkEntryContent(entryLF, expected, CONTENT_LF);
		checkEntryContent(entryMixed, expected, CONTENT_LF);
	}

	@Test
	public void test_ConfigAutoCRLF_true() throws Exception {
		// for EOL to work, the text attribute must be set
		setupGitAndDoHardReset(AutoCRLF.TRUE, null, null, null, "* text=auto");
		collectRepositoryState();
		assertEquals("text=auto", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
	}

	@Test
	public void test_ConfigAutoCRLF_input() throws Exception {
		// for EOL to work, the text attribute must be set
		setupGitAndDoHardReset(AutoCRLF.INPUT, null, null, null, "* text=auto");
		collectRepositoryState();
		assertEquals("text=auto", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_LF, CONTENT_LF);
	}

	@Test
	public void test_ConfigEOL_lf() throws Exception {
		// for EOL to work, the text attribute must be set
		setupGitAndDoHardReset(null, EOL.LF, "*.txt text", null, null);
		collectRepositoryState();
		assertEquals("text", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_LF, CONTENT_LF);
	}

	@Test
	public void test_ConfigEOL_crlf() throws Exception {
		// for EOL to work, the text attribute must be set
		setupGitAndDoHardReset(null, EOL.CRLF, "*.txt text", null, null);
		collectRepositoryState();
		assertEquals("text", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
	}

	@Test
	public void test_ConfigEOL_native_windows() throws Exception {
		mockSystemReader.setWindows();
		// for EOL to work, the text attribute must be set
		setupGitAndDoHardReset(null, EOL.NATIVE, "*.txt text", null, null);
		collectRepositoryState();
		assertEquals("text", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
	}

	@Test
	public void test_ConfigEOL_native_xnix() throws Exception {
		mockSystemReader.setUnix();
		// for EOL to work, the text attribute must be set
		setupGitAndDoHardReset(null, EOL.NATIVE, "*.txt text", null, null);
		collectRepositoryState();
		assertEquals("text", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
	}

	@Test
	public void test_ConfigAutoCRLF_false_ConfigEOL_lf() throws Exception {
		// for EOL to work, the text attribute must be set
		setupGitAndDoHardReset(AutoCRLF.FALSE, EOL.LF, "*.txt text", null, null);
		collectRepositoryState();
		assertEquals("text", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_LF, CONTENT_LF);
	}

	@Test
	public void test_ConfigAutoCRLF_false_ConfigEOL_native() throws Exception {
		// for EOL to work, the text attribute must be set
		setupGitAndDoHardReset(AutoCRLF.FALSE, EOL.NATIVE, "*.txt text", null, null);
		collectRepositoryState();
		assertEquals("text", entryCRLF.attrs);
		String expected = isDefaultCrLf() ? CONTENT_CRLF : CONTENT_LF;
		checkEntryContent(entryCRLF, expected, CONTENT_LF);
		checkEntryContent(entryLF, expected, CONTENT_LF);
		checkEntryContent(entryMixed, expected, CONTENT_LF);
	}

	@Test
	public void test_ConfigAutoCRLF_true_ConfigEOL_lf() throws Exception {
		// for EOL to work, the text attribute must be set
		setupGitAndDoHardReset(AutoCRLF.TRUE, EOL.LF, "*.txt text", null, null);
		collectRepositoryState();
		assertEquals("text", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
	}

	@Test
	public void test_switchToBranchWithTextAttributes()
			throws Exception {
		Git git = Git.wrap(db);

		// for EOL to work, the text attribute must be set
		setupGitAndDoHardReset(AutoCRLF.FALSE, EOL.CRLF, null, null,
				"file1.txt text\nfile2.txt text\nfile3.txt text");
		collectRepositoryState();
		assertEquals("text", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);

		// switch to binary for file1
		dotGitattributes = createAndAddFile(git, Constants.DOT_GIT_ATTRIBUTES,
				"file1.txt binary\nfile2.txt text\nfile3.txt text");
		gitCommit(git, "switchedToBinaryFor1");
		recreateWorktree(git);
		collectRepositoryState();
		assertEquals("binary -diff -merge -text", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
		assertEquals("text", entryLF.attrs);
		checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
		assertEquals("text", entryMixed.attrs);
		checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);

		// checkout the commit which has text for file1
		gitCheckout(git, "HEAD^");
		recreateWorktree(git);
		collectRepositoryState();
		assertEquals("text", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
	}

	@Test
	public void test_switchToBranchWithBinaryAttributes() throws Exception {
		Git git = Git.wrap(db);

		// for EOL to work, the text attribute must be set
		setupGitAndDoHardReset(AutoCRLF.FALSE, EOL.LF, null, null,
				"file1.txt binary\nfile2.txt binary\nfile3.txt binary");
		collectRepositoryState();
		assertEquals("binary -diff -merge -text", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_CRLF);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_MIXED, CONTENT_MIXED);

		// switch to text for file1
		dotGitattributes = createAndAddFile(git, Constants.DOT_GIT_ATTRIBUTES,
				"file1.txt text\nfile2.txt binary\nfile3.txt binary");
		gitCommit(git, "switchedToTextFor1");
		recreateWorktree(git);
		collectRepositoryState();
		assertEquals("text", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
		assertEquals("binary -diff -merge -text", entryLF.attrs);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
		assertEquals("binary -diff -merge -text", entryMixed.attrs);
		checkEntryContent(entryMixed, CONTENT_MIXED, CONTENT_MIXED);

		// checkout the commit which has text for file1
		gitCheckout(git, "HEAD^");
		recreateWorktree(git);
		collectRepositoryState();
		assertEquals("binary -diff -merge -text", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_CRLF);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_MIXED, CONTENT_MIXED);
	}

	@Test
	public void test_ConfigAutoCRLF_input_ConfigEOL_lf() throws Exception {
		// for EOL to work, the text attribute must be set
		setupGitAndDoHardReset(AutoCRLF.INPUT, EOL.LF, "*.txt text", null, null);
		collectRepositoryState();
		assertEquals("text", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_LF, CONTENT_LF);
	}

	@Test
	public void test_ConfigAutoCRLF_true_GlobalEOL_lf() throws Exception {
		setupGitAndDoHardReset(AutoCRLF.TRUE, EOL.LF, "*.txt eol=lf", null, null);
		collectRepositoryState();
		assertEquals("eol=lf", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_LF, CONTENT_LF);
	}

	@Test
	public void test_ConfigAutoCRLF_false_GlobalEOL_lf() throws Exception {
		setupGitAndDoHardReset(AutoCRLF.FALSE, EOL.LF, "*.txt eol=lf", null, null);
		collectRepositoryState();
		assertEquals("eol=lf", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_LF, CONTENT_LF);
	}

	@Test
	public void test_ConfigAutoCRLF_input_GlobalEOL_lf() throws Exception {
		setupGitAndDoHardReset(AutoCRLF.INPUT, EOL.LF, "*.txt eol=lf", null, null);
		collectRepositoryState();
		assertEquals("eol=lf", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_LF, CONTENT_LF);
	}

	@Test
	public void test_ConfigAutoCRLF_true_GlobalEOL_crlf() throws Exception {
		setupGitAndDoHardReset(AutoCRLF.TRUE, EOL.LF, "*.txt eol=crlf", null, null);
		collectRepositoryState();
		assertEquals("eol=crlf", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
	}

	@Test
	public void test_ConfigAutoCRLF_false_GlobalEOL_crlf() throws Exception {
		setupGitAndDoHardReset(AutoCRLF.FALSE, EOL.LF, "*.txt eol=crlf", null, null);
		collectRepositoryState();
		assertEquals("eol=crlf", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
	}

	@Test
	public void test_ConfigAutoCRLF_input_GlobalEOL_crlf() throws Exception {
		setupGitAndDoHardReset(AutoCRLF.INPUT, EOL.LF, "*.txt eol=crlf", null, null);
		collectRepositoryState();
		assertEquals("eol=crlf", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
	}

	@Test
	public void test_ConfigAutoCRLF_true_GlobalEOL_lf_InfoEOL_crlf()
			throws Exception {
		setupGitAndDoHardReset(AutoCRLF.TRUE, null, "*.txt eol=lf", "*.txt eol=crlf", null);
		// info decides
		collectRepositoryState();
		assertEquals("eol=crlf", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
	}

	@Test
	public void test_ConfigAutoCRLF_false_GlobalEOL_crlf_InfoEOL_lf()
			throws Exception {
		setupGitAndDoHardReset(AutoCRLF.FALSE, null, "*.txt eol=crlf", "*.txt eol=lf", null);
		// info decides
		collectRepositoryState();
		assertEquals("eol=lf", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_LF, CONTENT_LF);
	}

	@Test
	public void test_GlobalEOL_lf_RootEOL_crlf() throws Exception {
		setupGitAndDoHardReset(null, null, "*.txt eol=lf", null, "*.txt eol=crlf");
		// root over global
		collectRepositoryState();
		assertEquals("eol=crlf", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
	}

	@Test
	public void test_GlobalEOL_lf_InfoEOL_crlf_RootEOL_lf() throws Exception {
		setupGitAndDoHardReset(null, null, "*.txt eol=lf", "*.txt eol=crlf", "*.txt eol=lf");
		// info overrides all
		collectRepositoryState();
		assertEquals("eol=crlf", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
	}

	@Test
	public void test_GlobalEOL_lf_InfoEOL_crlf_RootEOL_unspec()
			throws Exception {
		setupGitAndDoHardReset(null, null, "*.txt eol=lf", "*.txt eol=crlf",
				"*.txt text !eol");
		// info overrides all
		collectRepositoryState();
		assertEquals("eol=crlf text", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_CRLF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_CRLF, CONTENT_LF);
	}

	@Test
	public void test_GlobalEOL_lf_InfoEOL_unspec_RootEOL_crlf()
			throws Exception {
		setupGitAndDoHardReset(null, null, "*.txt eol=lf", "*.txt !eol",
				"*.txt text eol=crlf");
		// info overrides all
		collectRepositoryState();
		assertEquals("text", entryCRLF.attrs);
		// !eol means unspecified, so use the default of core.eol, which is
		// native.
		String expected = isDefaultCrLf() ? CONTENT_CRLF : CONTENT_LF;
		checkEntryContent(entryCRLF, expected, CONTENT_LF);
		checkEntryContent(entryLF, expected, CONTENT_LF);
		checkEntryContent(entryMixed, expected, CONTENT_LF);
	}

	@Test
	public void testBinary1() throws Exception {
		setupGitAndDoHardReset(AutoCRLF.TRUE, EOL.CRLF, "*.txt text", "*.txt binary",
				"*.txt eol=crlf");
		// info overrides all
		collectRepositoryState();
		assertEquals("binary -diff -merge -text eol=crlf", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_CRLF);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_MIXED, CONTENT_MIXED);
	}

	@Test
	public void testBinary2() throws Exception {
		setupGitAndDoHardReset(AutoCRLF.TRUE, EOL.CRLF, "*.txt text eol=crlf", null,
				"*.txt binary");
		// root over global
		collectRepositoryState();
		assertEquals("binary -diff -merge -text eol=crlf", entryCRLF.attrs);
		checkEntryContent(entryCRLF, CONTENT_CRLF, CONTENT_CRLF);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_MIXED, CONTENT_MIXED);
	}

	// create new repo with
	// global .gitattributes
	// info .git/config/info/.gitattributes
	// workdir root .gitattributes
	// text file lf.txt CONTENT_LF
	// text file crlf.txt CONTENT_CRLF
	//
	// commit files (checkin)
	// delete working dir files
	// reset hard (checkout)
	private void setupGitAndDoHardReset(AutoCRLF autoCRLF, EOL eol,
			String globalAttributesContent, String infoAttributesContent,
			String workDirRootAttributesContent) throws Exception {
		Git git = new Git(db);
		FileBasedConfig config = db.getConfig();
		if (autoCRLF != null) {
			config.setEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
					ConfigConstants.CONFIG_KEY_AUTOCRLF, autoCRLF);
		}
		if (eol != null) {
			config.setEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
					ConfigConstants.CONFIG_KEY_EOL, eol);
		}
		if (globalAttributesContent != null) {
			File f = new File(db.getDirectory(), "global/attrs");
			write(f, globalAttributesContent);
			config.setString(ConfigConstants.CONFIG_CORE_SECTION, null,
					ConfigConstants.CONFIG_KEY_ATTRIBUTESFILE,
					f.getAbsolutePath());

		}
		if (infoAttributesContent != null) {
			File f = new File(db.getDirectory(), Constants.INFO_ATTRIBUTES);
			write(f, infoAttributesContent);
		}
		config.save();

		if (workDirRootAttributesContent != null) {
			dotGitattributes = createAndAddFile(git,
					Constants.DOT_GIT_ATTRIBUTES, workDirRootAttributesContent);
		} else {
			dotGitattributes = null;
		}

		fileCRLF = createAndAddFile(git, "file1.txt", "a");

		fileLF = createAndAddFile(git, "file2.txt", "a");

		fileMixed = createAndAddFile(git, "file3.txt", "a");

		RevCommit c = gitCommit(git, "create files");

		fileCRLF = createAndAddFile(git, "file1.txt", CONTENT_CRLF);

		fileLF = createAndAddFile(git, "file2.txt", CONTENT_LF);

		fileMixed = createAndAddFile(git, "file3.txt", CONTENT_MIXED);

		gitCommit(git, "addFiles");

		recreateWorktree(git);

		if (smudge) {
			DirCache dc = DirCache.lock(git.getRepository().getIndexFile(),
					FS.detect());
			DirCacheEditor editor = dc.editor();
			for (int i = 0; i < dc.getEntryCount(); i++) {
				editor.add(new DirCacheEditor.PathEdit(
						dc.getEntry(i).getPathString()) {
					@Override
					public void apply(DirCacheEntry ent) {
						ent.smudgeRacilyClean();
					}
				});
			}
			editor.commit();
		}

		// @TODO: find out why the following assertion would break the tests
		// assertTrue(git.status().call().isClean());
		git.checkout().setName(c.getName()).call();
		git.checkout().setName("master").call();
	}

	private void recreateWorktree(Git git)
			throws GitAPIException, CheckoutConflictException,
			InterruptedException, IOException, NoFilepatternException {
		// re-create file from the repo
		for (File f : new File[] { dotGitattributes, fileCRLF, fileLF, fileMixed }) {
			if (f == null)
				continue;
			f.delete();
			Assert.assertFalse(f.exists());
		}
		gitResetHard(git);
		fsTick(db.getIndexFile());
		gitAdd(git, ".");
	}

	protected RevCommit gitCommit(Git git, String msg) throws GitAPIException {
		return git.commit().setMessage(msg).call();
	}

	protected void gitAdd(Git git, String path) throws GitAPIException {
		git.add().addFilepattern(path).call();
	}

	protected void gitResetHard(Git git) throws GitAPIException {
		git.reset().setMode(ResetType.HARD).call();
	}

	protected void gitCheckout(Git git, String revstr)
			throws GitAPIException, RevisionSyntaxException, IOException {
		git.checkout().setName(db.resolve(revstr).getName()).call();
	}

	// create a file and add it to the repo
	private File createAndAddFile(Git git, String path, String content)
			throws Exception {
		File f;
		int pos = path.lastIndexOf('/');
		if (pos < 0) {
			f = writeTrashFile(path, content);
		} else {
			f = writeTrashFile(path.substring(0, pos), path.substring(pos + 1),
					content);
		}
		gitAdd(git, path);
		Assert.assertTrue(f.exists());
		return f;
	}

	private void collectRepositoryState() throws Exception {
		dirCache = db.readDirCache();
		try (TreeWalk walk = new TreeWalk(db)) {
			walk.addTree(new FileTreeIterator(db));
			walk.addTree(new DirCacheIterator(db.readDirCache()));
			if (dotGitattributes != null) {
				collectEntryContentAndAttributes(walk, F, ".gitattributes",
						null);
			}
			collectEntryContentAndAttributes(walk, F, fileCRLF.getName(),
					entryCRLF);
			collectEntryContentAndAttributes(walk, F, fileLF.getName(),
					entryLF);
			collectEntryContentAndAttributes(walk, F, fileMixed.getName(),
					entryMixed);
			assertFalse("Not all files tested", walk.next());
		}
	}

	private void collectEntryContentAndAttributes(TreeWalk walk, FileMode type,
			String pathName,
			ActualEntry e) throws IOException {
		assertTrue("walk has entry", walk.next());

		assertEquals(pathName, walk.getPathString());
		assertEquals(type, walk.getFileMode(0));

		if (e != null) {
			e.attrs = "";
			for (Attribute a : walk.getAttributes().getAll()) {
				e.attrs += " " + a.toString();
			}
			e.attrs = e.attrs.trim();
			e.file = new String(
					IO.readFully(new File(db.getWorkTree(), pathName)), UTF_8);
			DirCacheEntry dce = dirCache.getEntry(pathName);
			ObjectLoader open = walk.getObjectReader().open(dce.getObjectId());
			e.index = new String(open.getBytes(), UTF_8);
			e.indexContentLength = dce.getLength();
		}

		if (D.equals(type))
			walk.enterSubtree();
	}
}
