/*
 * Copyright (C) 2011-2012, GitHub Inc. 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 org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;

import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicInteger;

import org.eclipse.jgit.api.CherryPickResult.CherryPickStatus;
import org.eclipse.jgit.api.errors.CanceledException;
import org.eclipse.jgit.api.errors.EmptyCommitException;
import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheBuilder;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.junit.time.TimeUtil;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.GpgSigner;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.ReflogEntry;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.lib.CommitConfig.CleanupMode;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.submodule.SubmoduleWalk;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.eclipse.jgit.util.FS;
import org.junit.Ignore;
import org.junit.Test;

/**
 * Unit tests of {@link CommitCommand}.
 */
public class CommitCommandTest extends RepositoryTestCase {

	@Test
	public void testExecutableRetention() throws Exception {
		StoredConfig config = db.getConfig();
		config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
				ConfigConstants.CONFIG_KEY_FILEMODE, true);
		config.save();

		FS executableFs = new FS() {

			@Override
			public boolean supportsExecute() {
				return true;
			}

			@Override
			public boolean setExecute(File f, boolean canExec) {
				return true;
			}

			@Override
			public ProcessBuilder runInShell(String cmd, String[] args) {
				return null;
			}

			@Override
			public boolean retryFailedLockFileCommit() {
				return false;
			}

			@Override
			public FS newInstance() {
				return this;
			}

			@Override
			protected File discoverGitExe() {
				return null;
			}

			@Override
			public boolean canExecute(File f) {
				return true;
			}

			@Override
			public boolean isCaseSensitive() {
				return true;
			}
		};

		Git git = Git.open(db.getDirectory(), executableFs);
		String path = "a.txt";
		writeTrashFile(path, "content");
		git.add().addFilepattern(path).call();
		RevCommit commit1 = git.commit().setMessage("commit").call();
		try (TreeWalk walk = TreeWalk.forPath(db, path, commit1.getTree())) {
			assertNotNull(walk);
			assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0));
		}

		FS nonExecutableFs = new FS() {

			@Override
			public boolean supportsExecute() {
				return false;
			}

			@Override
			public boolean setExecute(File f, boolean canExec) {
				return false;
			}

			@Override
			public ProcessBuilder runInShell(String cmd, String[] args) {
				return null;
			}

			@Override
			public boolean retryFailedLockFileCommit() {
				return false;
			}

			@Override
			public FS newInstance() {
				return this;
			}

			@Override
			protected File discoverGitExe() {
				return null;
			}

			@Override
			public boolean canExecute(File f) {
				return false;
			}

			@Override
			public boolean isCaseSensitive() {
				return true;
			}
		};

		config = db.getConfig();
		config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
				ConfigConstants.CONFIG_KEY_FILEMODE, false);
		config.save();

		Git git2 = Git.open(db.getDirectory(), nonExecutableFs);
		writeTrashFile(path, "content2");
		RevCommit commit2 = git2.commit().setOnly(path).setMessage("commit2")
				.call();
		try (TreeWalk walk = TreeWalk.forPath(db, path, commit2.getTree())) {
			assertNotNull(walk);
			assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0));
		}
	}

	@Test
	public void commitNewSubmodule() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("file.txt", "content");
			git.add().addFilepattern("file.txt").call();
			RevCommit commit = git.commit().setMessage("create file").call();

			SubmoduleAddCommand command = new SubmoduleAddCommand(db);
			String path = "sub";
			command.setPath(path);
			String uri = db.getDirectory().toURI().toString();
			command.setURI(uri);
			Repository repo = command.call();
			assertNotNull(repo);
			addRepoToClose(repo);

			try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
				assertTrue(generator.next());
				assertEquals(path, generator.getPath());
				assertEquals(commit, generator.getObjectId());
				assertEquals(uri, generator.getModulesUrl());
				assertEquals(path, generator.getModulesPath());
				assertEquals(uri, generator.getConfigUrl());
				try (Repository subModRepo = generator.getRepository()) {
					assertNotNull(subModRepo);
				}
			}
			assertEquals(commit, repo.resolve(Constants.HEAD));

			RevCommit submoduleCommit = git.commit().setMessage("submodule add")
					.setOnly(path).call();
			assertNotNull(submoduleCommit);
			try (TreeWalk walk = new TreeWalk(db)) {
				walk.addTree(commit.getTree());
				walk.addTree(submoduleCommit.getTree());
				walk.setFilter(TreeFilter.ANY_DIFF);
				List<DiffEntry> diffs = DiffEntry.scan(walk);
				assertEquals(1, diffs.size());
				DiffEntry subDiff = diffs.get(0);
				assertEquals(FileMode.MISSING, subDiff.getOldMode());
				assertEquals(FileMode.GITLINK, subDiff.getNewMode());
				assertEquals(ObjectId.zeroId(), subDiff.getOldId().toObjectId());
				assertEquals(commit, subDiff.getNewId().toObjectId());
				assertEquals(path, subDiff.getNewPath());
			}
		}
	}

	@Test
	public void commitSubmoduleUpdate() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("file.txt", "content");
			git.add().addFilepattern("file.txt").call();
			RevCommit commit = git.commit().setMessage("create file").call();
			writeTrashFile("file.txt", "content2");
			git.add().addFilepattern("file.txt").call();
			RevCommit commit2 = git.commit().setMessage("edit file").call();

			SubmoduleAddCommand command = new SubmoduleAddCommand(db);
			String path = "sub";
			command.setPath(path);
			String uri = db.getDirectory().toURI().toString();
			command.setURI(uri);
			Repository repo = command.call();
			assertNotNull(repo);
			addRepoToClose(repo);

			try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
				assertTrue(generator.next());
				assertEquals(path, generator.getPath());
				assertEquals(commit2, generator.getObjectId());
				assertEquals(uri, generator.getModulesUrl());
				assertEquals(path, generator.getModulesPath());
				assertEquals(uri, generator.getConfigUrl());
				try (Repository subModRepo = generator.getRepository()) {
					assertNotNull(subModRepo);
				}
			}
			assertEquals(commit2, repo.resolve(Constants.HEAD));

			RevCommit submoduleAddCommit = git.commit().setMessage("submodule add")
					.setOnly(path).call();
			assertNotNull(submoduleAddCommit);

			RefUpdate update = repo.updateRef(Constants.HEAD);
			update.setNewObjectId(commit);
			assertEquals(Result.FORCED, update.forceUpdate());

			RevCommit submoduleEditCommit = git.commit()
					.setMessage("submodule add").setOnly(path).call();
			assertNotNull(submoduleEditCommit);
			try (TreeWalk walk = new TreeWalk(db)) {
				walk.addTree(submoduleAddCommit.getTree());
				walk.addTree(submoduleEditCommit.getTree());
				walk.setFilter(TreeFilter.ANY_DIFF);
				List<DiffEntry> diffs = DiffEntry.scan(walk);
				assertEquals(1, diffs.size());
				DiffEntry subDiff = diffs.get(0);
				assertEquals(FileMode.GITLINK, subDiff.getOldMode());
				assertEquals(FileMode.GITLINK, subDiff.getNewMode());
				assertEquals(commit2, subDiff.getOldId().toObjectId());
				assertEquals(commit, subDiff.getNewId().toObjectId());
				assertEquals(path, subDiff.getNewPath());
				assertEquals(path, subDiff.getOldPath());
			}
		}
	}

	@Ignore("very flaky when run with Hudson")
	@Test
	public void commitUpdatesSmudgedEntries() throws Exception {
		try (Git git = new Git(db)) {
			File file1 = writeTrashFile("file1.txt", "content1");
			TimeUtil.setLastModifiedWithOffset(file1.toPath(), -5000L);
			File file2 = writeTrashFile("file2.txt", "content2");
			TimeUtil.setLastModifiedWithOffset(file2.toPath(), -5000L);
			File file3 = writeTrashFile("file3.txt", "content3");
			TimeUtil.setLastModifiedWithOffset(file3.toPath(), -5000L);

			assertNotNull(git.add().addFilepattern("file1.txt")
					.addFilepattern("file2.txt").addFilepattern("file3.txt").call());
			RevCommit commit = git.commit().setMessage("add files").call();
			assertNotNull(commit);

			DirCache cache = DirCache.read(db.getIndexFile(), db.getFS());
			int file1Size = cache.getEntry("file1.txt").getLength();
			int file2Size = cache.getEntry("file2.txt").getLength();
			int file3Size = cache.getEntry("file3.txt").getLength();
			ObjectId file2Id = cache.getEntry("file2.txt").getObjectId();
			ObjectId file3Id = cache.getEntry("file3.txt").getObjectId();
			assertTrue(file1Size > 0);
			assertTrue(file2Size > 0);
			assertTrue(file3Size > 0);

			// Smudge entries
			cache = DirCache.lock(db.getIndexFile(), db.getFS());
			cache.getEntry("file1.txt").setLength(0);
			cache.getEntry("file2.txt").setLength(0);
			cache.getEntry("file3.txt").setLength(0);
			cache.write();
			assertTrue(cache.commit());

			// Verify entries smudged
			cache = DirCache.read(db.getIndexFile(), db.getFS());
			assertEquals(0, cache.getEntry("file1.txt").getLength());
			assertEquals(0, cache.getEntry("file2.txt").getLength());
			assertEquals(0, cache.getEntry("file3.txt").getLength());

			TimeUtil.setLastModifiedWithOffset(db.getIndexFile().toPath(),
					-5000L);

			write(file1, "content4");

			TimeUtil.setLastModifiedWithOffset(file1.toPath(), 2500L);
			assertNotNull(git.commit().setMessage("edit file").setOnly("file1.txt")
					.call());

			cache = db.readDirCache();
			assertEquals(file1Size, cache.getEntry("file1.txt").getLength());
			assertEquals(file2Size, cache.getEntry("file2.txt").getLength());
			assertEquals(file3Size, cache.getEntry("file3.txt").getLength());
			assertEquals(file2Id, cache.getEntry("file2.txt").getObjectId());
			assertEquals(file3Id, cache.getEntry("file3.txt").getObjectId());
		}
	}

	@Ignore("very flaky when run with Hudson")
	@Test
	public void commitIgnoresSmudgedEntryWithDifferentId() throws Exception {
		try (Git git = new Git(db)) {
			File file1 = writeTrashFile("file1.txt", "content1");
			TimeUtil.setLastModifiedWithOffset(file1.toPath(), -5000L);
			File file2 = writeTrashFile("file2.txt", "content2");
			TimeUtil.setLastModifiedWithOffset(file2.toPath(), -5000L);

			assertNotNull(git.add().addFilepattern("file1.txt")
					.addFilepattern("file2.txt").call());
			RevCommit commit = git.commit().setMessage("add files").call();
			assertNotNull(commit);

			DirCache cache = DirCache.read(db.getIndexFile(), db.getFS());
			int file1Size = cache.getEntry("file1.txt").getLength();
			int file2Size = cache.getEntry("file2.txt").getLength();
			assertTrue(file1Size > 0);
			assertTrue(file2Size > 0);

			writeTrashFile("file2.txt", "content3");
			assertNotNull(git.add().addFilepattern("file2.txt").call());
			writeTrashFile("file2.txt", "content4");

			// Smudge entries
			cache = DirCache.lock(db.getIndexFile(), db.getFS());
			cache.getEntry("file1.txt").setLength(0);
			cache.getEntry("file2.txt").setLength(0);
			cache.write();
			assertTrue(cache.commit());

			// Verify entries smudged
			cache = db.readDirCache();
			assertEquals(0, cache.getEntry("file1.txt").getLength());
			assertEquals(0, cache.getEntry("file2.txt").getLength());

			TimeUtil.setLastModifiedWithOffset(db.getIndexFile().toPath(),
					-5000L);

			write(file1, "content5");
			TimeUtil.setLastModifiedWithOffset(file1.toPath(), 1000L);

			assertNotNull(git.commit().setMessage("edit file").setOnly("file1.txt")
					.call());

			cache = db.readDirCache();
			assertEquals(file1Size, cache.getEntry("file1.txt").getLength());
			assertEquals(0, cache.getEntry("file2.txt").getLength());
		}
	}

	@Test
	public void commitAfterSquashMerge() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("file1", "file1");
			git.add().addFilepattern("file1").call();
			RevCommit first = git.commit().setMessage("initial commit").call();

			assertTrue(new File(db.getWorkTree(), "file1").exists());
			createBranch(first, "refs/heads/branch1");
			checkoutBranch("refs/heads/branch1");

			writeTrashFile("file2", "file2");
			git.add().addFilepattern("file2").call();
			git.commit().setMessage("second commit").call();
			assertTrue(new File(db.getWorkTree(), "file2").exists());

			checkoutBranch("refs/heads/master");

			MergeResult result = git.merge()
					.include(db.exactRef("refs/heads/branch1"))
					.setSquash(true)
					.call();

			assertTrue(new File(db.getWorkTree(), "file1").exists());
			assertTrue(new File(db.getWorkTree(), "file2").exists());
			assertEquals(MergeResult.MergeStatus.FAST_FORWARD_SQUASHED,
					result.getMergeStatus());

			// comment not set, should be inferred from SQUASH_MSG
			RevCommit squashedCommit = git.commit().call();

			assertEquals(1, squashedCommit.getParentCount());
			assertNull(db.readSquashCommitMsg());
			assertEquals("commit: Squashed commit of the following:", db
					.getReflogReader(Constants.HEAD).getLastEntry().getComment());
			assertEquals("commit: Squashed commit of the following:", db
					.getReflogReader(db.getBranch()).getLastEntry().getComment());
		}
	}

	@Test
	public void testReflogs() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("f", "1");
			git.add().addFilepattern("f").call();
			git.commit().setMessage("c1").call();
			writeTrashFile("f", "2");
			git.commit().setMessage("c2").setAll(true).setReflogComment(null)
					.call();
			writeTrashFile("f", "3");
			git.commit().setMessage("c3").setAll(true)
					.setReflogComment("testRl").call();

			db.getReflogReader(Constants.HEAD).getReverseEntries();

			assertEquals("testRl;commit (initial): c1;", reflogComments(
					db.getReflogReader(Constants.HEAD).getReverseEntries()));
			assertEquals("testRl;commit (initial): c1;", reflogComments(
					db.getReflogReader(db.getBranch()).getReverseEntries()));
		}
	}

	private static String reflogComments(List<ReflogEntry> entries) {
		StringBuilder b = new StringBuilder();
		for (ReflogEntry e : entries) {
			b.append(e.getComment()).append(";");
		}
		return b.toString();
	}

	@Test(expected = WrongRepositoryStateException.class)
	public void commitAmendOnInitialShouldFail() throws Exception {
		try (Git git = new Git(db)) {
			git.commit().setAmend(true).setMessage("initial commit").call();
		}
	}

	@Test
	public void commitAmendWithoutAuthorShouldSetOriginalAuthorAndAuthorTime()
			throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("file1", "file1");
			git.add().addFilepattern("file1").call();

			final String authorName = "First Author";
			final String authorEmail = "author@example.org";
			final Date authorDate = new Date(1349621117000L);
			PersonIdent firstAuthor = new PersonIdent(authorName, authorEmail,
					authorDate, TimeZone.getTimeZone("UTC"));
			git.commit().setMessage("initial commit").setAuthor(firstAuthor).call();

			RevCommit amended = git.commit().setAmend(true)
					.setMessage("amend commit").call();

			PersonIdent amendedAuthor = amended.getAuthorIdent();
			assertEquals(authorName, amendedAuthor.getName());
			assertEquals(authorEmail, amendedAuthor.getEmailAddress());
			assertEquals(authorDate.getTime(), amendedAuthor.getWhen().getTime());
		}
	}

	@Test
	public void commitAmendWithAuthorShouldUseIt() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("file1", "file1");
			git.add().addFilepattern("file1").call();
			git.commit().setMessage("initial commit").call();

			RevCommit amended = git.commit().setAmend(true)
					.setAuthor("New Author", "newauthor@example.org")
					.setMessage("amend commit").call();

			PersonIdent amendedAuthor = amended.getAuthorIdent();
			assertEquals("New Author", amendedAuthor.getName());
			assertEquals("newauthor@example.org", amendedAuthor.getEmailAddress());
		}
	}

	@Test
	public void commitMessageVerbatim() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("file1", "file1");
			git.add().addFilepattern("file1").call();
			RevCommit committed = git.commit().setMessage("#initial commit")
					.call();

			assertEquals("#initial commit", committed.getFullMessage());
		}
	}

	@Test
	public void commitMessageStrip() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("file1", "file1");
			git.add().addFilepattern("file1").call();
			RevCommit committed = git.commit().setMessage(
					"#Comment\ninitial commit\t\n\n commit body \n \t#another comment")
					.setCleanupMode(CleanupMode.STRIP).call();

			assertEquals("initial commit\n\n commit body",
					committed.getFullMessage());
		}
	}

	@Test
	public void commitMessageDefault() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("file1", "file1");
			git.add().addFilepattern("file1").call();
			RevCommit committed = git.commit().setMessage(
					"#Comment\ninitial commit\t\n\n commit body \n\n\n \t#another comment  ")
					.setCleanupMode(CleanupMode.DEFAULT).call();

			assertEquals("initial commit\n\n commit body",
					committed.getFullMessage());
		}
	}

	@Test
	public void commitMessageDefaultWhitespace() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("file1", "file1");
			git.add().addFilepattern("file1").call();
			RevCommit committed = git.commit().setMessage(
					"#Comment\ninitial commit\t\n\n commit body \n\n\n \t#another comment  ")
					.setCleanupMode(CleanupMode.DEFAULT).setDefaultClean(false)
					.call();

			assertEquals(
					"#Comment\ninitial commit\n\n commit body\n\n \t#another comment",
					committed.getFullMessage());
		}
	}

	@Test
	public void commitEmptyCommits() throws Exception {
		try (Git git = new Git(db)) {

			writeTrashFile("file1", "file1");
			git.add().addFilepattern("file1").call();
			RevCommit initial = git.commit().setMessage("initial commit")
					.call();

			RevCommit emptyFollowUp = git.commit()
					.setAuthor("New Author", "newauthor@example.org")
					.setMessage("no change").call();

			assertNotEquals(initial.getId(), emptyFollowUp.getId());
			assertEquals(initial.getTree().getId(),
					emptyFollowUp.getTree().getId());

			try {
				git.commit().setAuthor("New Author", "newauthor@example.org")
						.setMessage("again no change").setAllowEmpty(false)
						.call();
				fail("Didn't get the expected EmptyCommitException");
			} catch (EmptyCommitException e) {
				// expect this exception
			}

			// Allow empty commits also when setOnly was set
			git.commit().setAuthor("New Author", "newauthor@example.org")
					.setMessage("again no change").setOnly("file1")
					.setAllowEmpty(true).call();
		}
	}

	@Test
	public void commitOnlyShouldCommitUnmergedPathAndNotAffectOthers()
			throws Exception {
		DirCache index = db.lockDirCache();
		DirCacheBuilder builder = index.builder();
		addUnmergedEntry("unmerged1", builder);
		addUnmergedEntry("unmerged2", builder);
		DirCacheEntry other = new DirCacheEntry("other");
		other.setFileMode(FileMode.REGULAR_FILE);
		builder.add(other);
		builder.commit();

		writeTrashFile("unmerged1", "unmerged1 data");
		writeTrashFile("unmerged2", "unmerged2 data");
		writeTrashFile("other", "other data");

		assertEquals("[other, mode:100644]"
				+ "[unmerged1, mode:100644, stage:1]"
				+ "[unmerged1, mode:100644, stage:2]"
				+ "[unmerged1, mode:100644, stage:3]"
				+ "[unmerged2, mode:100644, stage:1]"
				+ "[unmerged2, mode:100644, stage:2]"
				+ "[unmerged2, mode:100644, stage:3]",
				indexState(0));

		try (Git git = new Git(db)) {
			RevCommit commit = git.commit().setOnly("unmerged1")
					.setMessage("Only one file").call();

			assertEquals("[other, mode:100644]" + "[unmerged1, mode:100644]"
					+ "[unmerged2, mode:100644, stage:1]"
					+ "[unmerged2, mode:100644, stage:2]"
					+ "[unmerged2, mode:100644, stage:3]",
					indexState(0));

			try (TreeWalk walk = TreeWalk.forPath(db, "unmerged1", commit.getTree())) {
				assertEquals(FileMode.REGULAR_FILE, walk.getFileMode(0));
			}
		}
	}

	@Test
	public void commitOnlyShouldHandleIgnored() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("subdir/foo", "Hello World");
			writeTrashFile("subdir/bar", "Hello World");
			writeTrashFile(".gitignore", "bar");
			git.add().addFilepattern("subdir").call();
			git.commit().setOnly("subdir").setMessage("first commit").call();
			assertEquals("[subdir/foo, mode:100644, content:Hello World]",
					indexState(CONTENT));
		}
	}

	private void nonNormalizedIndexTest(boolean executable) throws Exception {
		String mode = executable ? "100755" : "100644";
		try (Git git = new Git(db)) {
			// Commit a file with CR/LF into the index
			FileBasedConfig config = db.getConfig();
			config.setString("core", null, "autocrlf", "false");
			config.save();
			File testFile = writeTrashFile("file.txt", "line 1\r\nline 2\r\n");
			if (executable) {
				FS.DETECTED.setExecute(testFile, true);
			}
			git.add().addFilepattern("file.txt").call();
			git.commit().setMessage("Initial").call();
			assertEquals(
					"[file.txt, mode:" + mode
							+ ", content:line 1\r\nline 2\r\n]",
					indexState(CONTENT));
			config.setString("core", null, "autocrlf", "true");
			config.save();
			writeTrashFile("file.txt", "line 1\r\nline 1.5\r\nline 2\r\n");
			testFile = writeTrashFile("file2.txt", "new\r\nfile\r\n");
			if (executable) {
				FS.DETECTED.setExecute(testFile, true);
			}
			git.add().addFilepattern("file.txt").addFilepattern("file2.txt")
					.call();
			git.commit().setMessage("Second").call();
			assertEquals(
					"[file.txt, mode:" + mode
							+ ", content:line 1\r\nline 1.5\r\nline 2\r\n]"
							+ "[file2.txt, mode:" + mode
							+ ", content:new\nfile\n]",
					indexState(CONTENT));
			writeTrashFile("file2.txt", "new\r\nfile\r\ncontent\r\n");
			git.add().addFilepattern("file2.txt").call();
			git.commit().setMessage("Third").call();
			assertEquals(
					"[file.txt, mode:" + mode
							+ ", content:line 1\r\nline 1.5\r\nline 2\r\n]"
							+ "[file2.txt, mode:" + mode
							+ ", content:new\nfile\ncontent\n]",
					indexState(CONTENT));
		}
	}

	@Test
	public void commitWithAutoCrlfAndNonNormalizedIndex() throws Exception {
		nonNormalizedIndexTest(false);
	}

	@Test
	public void commitExecutableWithAutoCrlfAndNonNormalizedIndex()
			throws Exception {
		assumeTrue(FS.DETECTED.supportsExecute());
		nonNormalizedIndexTest(true);
	}

	@Test
	public void testDeletionConflictWithAutoCrlf() throws Exception {
		try (Git git = new Git(db)) {
			// Commit a file with CR/LF into the index
			FileBasedConfig config = db.getConfig();
			config.setString("core", null, "autocrlf", "false");
			config.save();
			File file = writeTrashFile("file.txt", "foo\r\n");
			git.add().addFilepattern("file.txt").call();
			git.commit().setMessage("Initial").call();
			// Switch to side branch
			git.checkout().setCreateBranch(true).setName("side").call();
			assertTrue(file.delete());
			git.rm().addFilepattern("file.txt").call();
			git.commit().setMessage("Side").call();
			// Switch on autocrlf=true
			config.setString("core", null, "autocrlf", "true");
			config.save();
			// Switch back to master and commit a conflict
			git.checkout().setName("master").call();
			writeTrashFile("file.txt", "foob\r\n");
			git.add().addFilepattern("file.txt").call();
			assertEquals("[file.txt, mode:100644, content:foob\r\n]",
					indexState(CONTENT));
			writeTrashFile("g", "file2.txt", "anything");
			git.add().addFilepattern("g/file2.txt");
			RevCommit master = git.commit().setMessage("Second").call();
			// Switch to side branch again so that the deletion is "ours"
			git.checkout().setName("side").call();
			// Cherry pick master: produces a delete-modify conflict.
			CherryPickResult pick = git.cherryPick().include(master).call();
			assertEquals("Expected a cherry-pick conflict",
					CherryPickStatus.CONFLICTING, pick.getStatus());
			// XXX: g/file2.txt should actually be staged already, but isn't.
			git.add().addFilepattern("g/file2.txt").call();
			// Resolve the conflict by taking the master version
			writeTrashFile("file.txt", "foob\r\n");
			git.add().addFilepattern("file.txt").call();
			git.commit().setMessage("Cherry").call();
			// We expect this to be committed with a single LF since there is no
			// "ours" stage.
			assertEquals(
					"[file.txt, mode:100644, content:foob\n]"
							+ "[g/file2.txt, mode:100644, content:anything]",
					indexState(CONTENT));
		}
	}

	private void testConflictWithAutoCrlf(String baseLf, String lf)
			throws Exception {
		try (Git git = new Git(db)) {
			// Commit a file with CR/LF into the index
			FileBasedConfig config = db.getConfig();
			config.setString("core", null, "autocrlf", "false");
			config.save();
			writeTrashFile("file.txt", "foo" + baseLf);
			git.add().addFilepattern("file.txt").call();
			git.commit().setMessage("Initial").call();
			// Switch to side branch
			git.checkout().setCreateBranch(true).setName("side").call();
			writeTrashFile("file.txt", "bar\r\n");
			git.add().addFilepattern("file.txt").call();
			RevCommit side = git.commit().setMessage("Side").call();
			// Switch back to master and commit a conflict with the given lf
			git.checkout().setName("master");
			writeTrashFile("file.txt", "foob" + lf);
			git.add().addFilepattern("file.txt").call();
			git.commit().setMessage("Second").call();
			// Switch on autocrlf=true
			config.setString("core", null, "autocrlf", "true");
			config.save();
			// Cherry pick side: conflict. Resolve with CR-LF and commit.
			CherryPickResult pick = git.cherryPick().include(side).call();
			assertEquals("Expected a cherry-pick conflict",
					CherryPickStatus.CONFLICTING, pick.getStatus());
			writeTrashFile("file.txt", "foobar\r\n");
			git.add().addFilepattern("file.txt").call();
			git.commit().setMessage("Second").call();
			assertEquals("[file.txt, mode:100644, content:foobar" + lf + "]",
					indexState(CONTENT));
		}
	}

	@Test
	public void commitConflictWithAutoCrlfBaseCrLfOursLf() throws Exception {
		testConflictWithAutoCrlf("\r\n", "\n");
	}

	@Test
	public void commitConflictWithAutoCrlfBaseLfOursLf() throws Exception {
		testConflictWithAutoCrlf("\n", "\n");
	}

	@Test
	public void commitConflictWithAutoCrlfBasCrLfOursCrLf() throws Exception {
		testConflictWithAutoCrlf("\r\n", "\r\n");
	}

	@Test
	public void commitConflictWithAutoCrlfBaseLfOursCrLf() throws Exception {
		testConflictWithAutoCrlf("\n", "\r\n");
	}

	private static void addUnmergedEntry(String file, DirCacheBuilder builder) {
		DirCacheEntry stage1 = new DirCacheEntry(file, DirCacheEntry.STAGE_1);
		DirCacheEntry stage2 = new DirCacheEntry(file, DirCacheEntry.STAGE_2);
		DirCacheEntry stage3 = new DirCacheEntry(file, DirCacheEntry.STAGE_3);
		stage1.setFileMode(FileMode.REGULAR_FILE);
		stage2.setFileMode(FileMode.REGULAR_FILE);
		stage3.setFileMode(FileMode.REGULAR_FILE);
		builder.add(stage1);
		builder.add(stage2);
		builder.add(stage3);
	}

	@Test
	public void callSignerWithProperSigningKey() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("file1", "file1");
			git.add().addFilepattern("file1").call();

			String[] signingKey = new String[1];
			PersonIdent[] signingCommitters = new PersonIdent[1];
			AtomicInteger callCount = new AtomicInteger();
			GpgSigner.setDefault(new GpgSigner() {
				@Override
				public void sign(CommitBuilder commit, String gpgSigningKey,
						PersonIdent signingCommitter, CredentialsProvider credentialsProvider) {
					signingKey[0] = gpgSigningKey;
					signingCommitters[0] = signingCommitter;
					callCount.incrementAndGet();
				}

				@Override
				public boolean canLocateSigningKey(String gpgSigningKey,
						PersonIdent signingCommitter,
						CredentialsProvider credentialsProvider)
						throws CanceledException {
					return false;
				}
			});

			// first call should use config, which is expected to be null at
			// this time
			git.commit().setCommitter(committer).setSign(Boolean.TRUE)
					.setMessage("initial commit")
					.call();
			assertNull(signingKey[0]);
			assertEquals(1, callCount.get());
			assertSame(committer, signingCommitters[0]);

			writeTrashFile("file2", "file2");
			git.add().addFilepattern("file2").call();

			// second commit applies config value
			String expectedConfigSigningKey = "config-" + System.nanoTime();
			StoredConfig config = git.getRepository().getConfig();
			config.setString("user", null, "signingKey",
					expectedConfigSigningKey);
			config.save();

			git.commit().setCommitter(committer).setSign(Boolean.TRUE)
					.setMessage("initial commit")
					.call();
			assertEquals(expectedConfigSigningKey, signingKey[0]);
			assertEquals(2, callCount.get());
			assertSame(committer, signingCommitters[0]);

			writeTrashFile("file3", "file3");
			git.add().addFilepattern("file3").call();

			// now use specific on api
			String expectedSigningKey = "my-" + System.nanoTime();
			git.commit().setCommitter(committer).setSign(Boolean.TRUE)
					.setSigningKey(expectedSigningKey)
					.setMessage("initial commit").call();
			assertEquals(expectedSigningKey, signingKey[0]);
			assertEquals(3, callCount.get());
			assertSame(committer, signingCommitters[0]);
		}
	}

	@Test
	public void callSignerOnlyWhenSigning() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("file1", "file1");
			git.add().addFilepattern("file1").call();

			AtomicInteger callCount = new AtomicInteger();
			GpgSigner.setDefault(new GpgSigner() {
				@Override
				public void sign(CommitBuilder commit, String gpgSigningKey,
						PersonIdent signingCommitter, CredentialsProvider credentialsProvider) {
					callCount.incrementAndGet();
				}

				@Override
				public boolean canLocateSigningKey(String gpgSigningKey,
						PersonIdent signingCommitter,
						CredentialsProvider credentialsProvider)
						throws CanceledException {
					return false;
				}
			});

			// first call should use config, which is expected to be null at
			// this time
			git.commit().setMessage("initial commit").call();
			assertEquals(0, callCount.get());

			writeTrashFile("file2", "file2");
			git.add().addFilepattern("file2").call();

			// now force signing
			git.commit().setSign(Boolean.TRUE).setMessage("commit").call();
			assertEquals(1, callCount.get());

			writeTrashFile("file3", "file3");
			git.add().addFilepattern("file3").call();

			// now rely on config
			StoredConfig config = git.getRepository().getConfig();
			config.setBoolean("commit", null, "gpgSign", true);
			config.save();

			git.commit().setMessage("commit").call();
			assertEquals(2, callCount.get());

			writeTrashFile("file4", "file4");
			git.add().addFilepattern("file4").call();

			// now force "no-sign" (even though config is true)
			git.commit().setSign(Boolean.FALSE).setMessage("commit").call();
			assertEquals(2, callCount.get());
		}
	}
}
