/*
 * Copyright (C) 2015, Ivan Motsch <ivan.motsch@bsiag.com>
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.eclipse.jgit.api;

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;

	private TreeWalk walk;

	/** 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;

	@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);
		checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_LF, 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);
		checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_LF, 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 {
		String origLineSeparator = System.getProperty("line.separator", "\n");
		System.setProperty("line.separator", "\r\n");
		try {
			// 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);
		} finally {
			System.setProperty("line.separator", origLineSeparator);
		}
	}

	@Test
	public void test_ConfigEOL_native_xnix() throws Exception {
		String origLineSeparator = System.getProperty("line.separator", "\n");
		System.setProperty("line.separator", "\n");
		try {
			// 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);
		} finally {
			System.setProperty("line.separator", origLineSeparator);
		}
	}

	@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);
		checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_LF, 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);
		checkEntryContent(entryCRLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryLF, CONTENT_LF, CONTENT_LF);
		checkEntryContent(entryMixed, CONTENT_LF, 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();
		walk = beginWalk();
		if (dotGitattributes != null)
			collectEntryContentAndAttributes(F, ".gitattributes", null);
		collectEntryContentAndAttributes(F, fileCRLF.getName(), entryCRLF);
		collectEntryContentAndAttributes(F, fileLF.getName(), entryLF);
		collectEntryContentAndAttributes(F, fileMixed.getName(), entryMixed);
		endWalk();
	}

	private TreeWalk beginWalk() throws Exception {
		TreeWalk newWalk = new TreeWalk(db);
		newWalk.addTree(new FileTreeIterator(db));
		newWalk.addTree(new DirCacheIterator(db.readDirCache()));
		return newWalk;
	}

	private void endWalk() throws IOException {
		assertFalse("Not all files tested", walk.next());
	}

	private void collectEntryContentAndAttributes(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)));
			DirCacheEntry dce = dirCache.getEntry(pathName);
			ObjectLoader open = walk.getObjectReader().open(dce.getObjectId());
			e.index = new String(open.getBytes());
			e.indexContentLength = dce.getLength();
		}

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