/*
 * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com>
 * Copyright (C) 2010-2014, Christian Halstrick <christian.halstrick@sap.com>
 * and other copyright owners as documented in the project's IP log.
 *
 * 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.eclipse.jgit.lib.Constants.MASTER;
import static org.eclipse.jgit.lib.Constants.R_HEADS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
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.Iterator;
import java.util.regex.Pattern;

import org.eclipse.jgit.api.MergeCommand.FastForwardMode;
import org.eclipse.jgit.api.MergeResult.MergeStatus;
import org.eclipse.jgit.api.errors.InvalidMergeHeadsException;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.junit.TestRepository.BranchBuilder;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryState;
import org.eclipse.jgit.lib.Sets;
import org.eclipse.jgit.merge.MergeStrategy;
import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils;
import org.eclipse.jgit.util.GitDateFormatter;
import org.eclipse.jgit.util.GitDateFormatter.Format;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;

@RunWith(Theories.class)
public class MergeCommandTest extends RepositoryTestCase {

	public static @DataPoints
	MergeStrategy[] mergeStrategies = MergeStrategy.get();

	private GitDateFormatter dateFormatter;

	@Override
	@Before
	public void setUp() throws Exception {
		super.setUp();
		dateFormatter = new GitDateFormatter(Format.DEFAULT);
	}

	@Test
	public void testMergeInItself() throws Exception {
		try (Git git = new Git(db)) {
			git.commit().setMessage("initial commit").call();

			MergeResult result = git.merge().include(db.exactRef(Constants.HEAD)).call();
			assertEquals(MergeResult.MergeStatus.ALREADY_UP_TO_DATE, result.getMergeStatus());
		}
		// no reflog entry written by merge
		assertEquals("commit (initial): initial commit",
				db
				.getReflogReader(Constants.HEAD).getLastEntry().getComment());
		assertEquals("commit (initial): initial commit",
				db
				.getReflogReader(db.getBranch()).getLastEntry().getComment());
	}

	@Test
	public void testAlreadyUpToDate() throws Exception {
		try (Git git = new Git(db)) {
			RevCommit first = git.commit().setMessage("initial commit").call();
			createBranch(first, "refs/heads/branch1");

			RevCommit second = git.commit().setMessage("second commit").call();
			MergeResult result = git.merge().include(db.exactRef("refs/heads/branch1")).call();
			assertEquals(MergeResult.MergeStatus.ALREADY_UP_TO_DATE, result.getMergeStatus());
			assertEquals(second, result.getNewHead());
		}
		// no reflog entry written by merge
		assertEquals("commit: second commit", db
				.getReflogReader(Constants.HEAD).getLastEntry().getComment());
		assertEquals("commit: second commit", db
				.getReflogReader(db.getBranch()).getLastEntry().getComment());
	}

	@Test
	public void testFastForward() throws Exception {
		try (Git git = new Git(db)) {
			RevCommit first = git.commit().setMessage("initial commit").call();
			createBranch(first, "refs/heads/branch1");

			RevCommit second = git.commit().setMessage("second commit").call();

			checkoutBranch("refs/heads/branch1");

			MergeResult result = git.merge().include(db.exactRef(R_HEADS + MASTER)).call();

			assertEquals(MergeResult.MergeStatus.FAST_FORWARD, result.getMergeStatus());
			assertEquals(second, result.getNewHead());
		}
		assertEquals("merge refs/heads/master: Fast-forward",
				db.getReflogReader(Constants.HEAD).getLastEntry().getComment());
		assertEquals("merge refs/heads/master: Fast-forward",
				db.getReflogReader(db.getBranch()).getLastEntry().getComment());
	}

	@Test
	public void testFastForwardNoCommit() throws Exception {
		try (Git git = new Git(db)) {
			RevCommit first = git.commit().setMessage("initial commit").call();
			createBranch(first, "refs/heads/branch1");

			RevCommit second = git.commit().setMessage("second commit").call();

			checkoutBranch("refs/heads/branch1");

			MergeResult result = git.merge().include(db.exactRef(R_HEADS + MASTER))
					.setCommit(false).call();

			assertEquals(MergeResult.MergeStatus.FAST_FORWARD,
					result.getMergeStatus());
			assertEquals(second, result.getNewHead());
		}
		assertEquals("merge refs/heads/master: Fast-forward", db
				.getReflogReader(Constants.HEAD).getLastEntry().getComment());
		assertEquals("merge refs/heads/master: Fast-forward", db
				.getReflogReader(db.getBranch()).getLastEntry().getComment());
	}

	@Test
	public void testFastForwardWithFiles() 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");

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

			checkoutBranch("refs/heads/branch1");
			assertFalse(new File(db.getWorkTree(), "file2").exists());

			MergeResult result = git.merge().include(db.exactRef(R_HEADS + MASTER)).call();

			assertTrue(new File(db.getWorkTree(), "file1").exists());
			assertTrue(new File(db.getWorkTree(), "file2").exists());
			assertEquals(MergeResult.MergeStatus.FAST_FORWARD, result.getMergeStatus());
			assertEquals(second, result.getNewHead());
		}
		assertEquals("merge refs/heads/master: Fast-forward",
				db.getReflogReader(Constants.HEAD).getLastEntry().getComment());
		assertEquals("merge refs/heads/master: Fast-forward",
				db.getReflogReader(db.getBranch()).getLastEntry().getComment());
	}

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

			writeTrashFile("file2", "file2");
			git.add().addFilepattern("file2").call();
			RevCommit second = git.commit().setMessage("second commit").call();

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

			checkoutBranch("refs/heads/branch1");
			assertFalse(new File(db.getWorkTree(), "file2").exists());
			assertFalse(new File(db.getWorkTree(), "file3").exists());

			MergeCommand merge = git.merge();
			merge.include(second.getId());
			merge.include(db.exactRef(R_HEADS + MASTER));
			try {
				merge.call();
				fail("Expected exception not thrown when merging multiple heads");
			} catch (InvalidMergeHeadsException e) {
				// expected this exception
			}
		}
	}

	@Theory
	public void testMergeSuccessAllStrategies(MergeStrategy mergeStrategy)
			throws Exception {
		try (Git git = new Git(db)) {
			RevCommit first = git.commit().setMessage("first").call();
			createBranch(first, "refs/heads/side");

			writeTrashFile("a", "a");
			git.add().addFilepattern("a").call();
			git.commit().setMessage("second").call();

			checkoutBranch("refs/heads/side");
			writeTrashFile("b", "b");
			git.add().addFilepattern("b").call();
			git.commit().setMessage("third").call();

			MergeResult result = git.merge().setStrategy(mergeStrategy)
					.include(db.exactRef(R_HEADS + MASTER)).call();
			assertEquals(MergeStatus.MERGED, result.getMergeStatus());
		}
		assertEquals(
				"merge refs/heads/master: Merge made by "
						+ mergeStrategy.getName() + ".",
				db.getReflogReader(Constants.HEAD).getLastEntry().getComment());
		assertEquals(
				"merge refs/heads/master: Merge made by "
						+ mergeStrategy.getName() + ".",
				db.getReflogReader(db.getBranch()).getLastEntry().getComment());
	}

	@Theory
	public void testMergeSuccessAllStrategiesNoCommit(
			MergeStrategy mergeStrategy) throws Exception {
		try (Git git = new Git(db)) {
			RevCommit first = git.commit().setMessage("first").call();
			createBranch(first, "refs/heads/side");

			writeTrashFile("a", "a");
			git.add().addFilepattern("a").call();
			git.commit().setMessage("second").call();

			checkoutBranch("refs/heads/side");
			writeTrashFile("b", "b");
			git.add().addFilepattern("b").call();
			RevCommit thirdCommit = git.commit().setMessage("third").call();

			MergeResult result = git.merge().setStrategy(mergeStrategy)
					.setCommit(false)
					.include(db.exactRef(R_HEADS + MASTER)).call();
			assertEquals(MergeStatus.MERGED_NOT_COMMITTED, result.getMergeStatus());
			assertEquals(db.exactRef(Constants.HEAD).getTarget().getObjectId(),
					thirdCommit.getId());
		}
	}

	@Test
	public void testContentMerge() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("a", "1\na\n3\n");
			writeTrashFile("b", "1\nb\n3\n");
			writeTrashFile("c/c/c", "1\nc\n3\n");
			git.add().addFilepattern("a").addFilepattern("b")
					.addFilepattern("c/c/c").call();
			RevCommit initialCommit = git.commit().setMessage("initial").call();

			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");

			writeTrashFile("a", "1\na(side)\n3\n");
			writeTrashFile("b", "1\nb(side)\n3\n");
			git.add().addFilepattern("a").addFilepattern("b").call();
			RevCommit secondCommit = git.commit().setMessage("side").call();

			assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
			checkoutBranch("refs/heads/master");
			assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));

			writeTrashFile("a", "1\na(main)\n3\n");
			writeTrashFile("c/c/c", "1\nc(main)\n3\n");
			git.add().addFilepattern("a").addFilepattern("c/c/c").call();
			git.commit().setMessage("main").call();

			MergeResult result = git.merge().include(secondCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();
			assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());

			assertEquals(
					"1\n<<<<<<< HEAD\na(main)\n=======\na(side)\n>>>>>>> 86503e7e397465588cc267b65d778538bffccb83\n3\n",
					read(new File(db.getWorkTree(), "a")));
			assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
			assertEquals("1\nc(main)\n3\n",
					read(new File(db.getWorkTree(), "c/c/c")));

			assertEquals(1, result.getConflicts().size());
			assertEquals(3, result.getConflicts().get("a")[0].length);

			assertEquals(RepositoryState.MERGING, db.getRepositoryState());
		}
	}

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

			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");

			writeTrashFile("b", "b");
			git.add().addFilepattern("b").call();
			RevCommit secondCommit = git.commit().setMessage("side").call();
			Ref tag = git.tag().setAnnotated(true).setMessage("my tag 01")
					.setName("tag01").setObjectId(secondCommit).call();

			checkoutBranch("refs/heads/master");

			writeTrashFile("a", "a2");
			git.add().addFilepattern("a").call();
			git.commit().setMessage("main").call();

			MergeResult result = git.merge().include(tag).setStrategy(MergeStrategy.RESOLVE).call();
			assertEquals(MergeStatus.MERGED, result.getMergeStatus());
		}
	}

	@Test
	public void testMergeMessage() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("a", "1\na\n3\n");
			git.add().addFilepattern("a").call();
			RevCommit initialCommit = git.commit().setMessage("initial").call();

			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");

			writeTrashFile("a", "1\na(side)\n3\n");
			git.add().addFilepattern("a").call();
			git.commit().setMessage("side").call();

			checkoutBranch("refs/heads/master");

			writeTrashFile("a", "1\na(main)\n3\n");
			git.add().addFilepattern("a").call();
			git.commit().setMessage("main").call();

			Ref sideBranch = db.exactRef("refs/heads/side");

			git.merge().include(sideBranch)
					.setStrategy(MergeStrategy.RESOLVE).call();

			assertEquals("Merge branch 'side'\n\nConflicts:\n\ta\n",
					db.readMergeCommitMsg());
		}

	}

	@Test
	public void testMergeNonVersionedPaths() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("a", "1\na\n3\n");
			writeTrashFile("b", "1\nb\n3\n");
			writeTrashFile("c/c/c", "1\nc\n3\n");
			git.add().addFilepattern("a").addFilepattern("b")
					.addFilepattern("c/c/c").call();
			RevCommit initialCommit = git.commit().setMessage("initial").call();

			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");

			writeTrashFile("a", "1\na(side)\n3\n");
			writeTrashFile("b", "1\nb(side)\n3\n");
			git.add().addFilepattern("a").addFilepattern("b").call();
			RevCommit secondCommit = git.commit().setMessage("side").call();

			assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
			checkoutBranch("refs/heads/master");
			assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));

			writeTrashFile("a", "1\na(main)\n3\n");
			writeTrashFile("c/c/c", "1\nc(main)\n3\n");
			git.add().addFilepattern("a").addFilepattern("c/c/c").call();
			git.commit().setMessage("main").call();

			writeTrashFile("d", "1\nd\n3\n");
			assertTrue(new File(db.getWorkTree(), "e").mkdir());

			MergeResult result = git.merge().include(secondCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();
			assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());

			assertEquals(
					"1\n<<<<<<< HEAD\na(main)\n=======\na(side)\n>>>>>>> 86503e7e397465588cc267b65d778538bffccb83\n3\n",
					read(new File(db.getWorkTree(), "a")));
			assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
			assertEquals("1\nc(main)\n3\n",
					read(new File(db.getWorkTree(), "c/c/c")));
			assertEquals("1\nd\n3\n", read(new File(db.getWorkTree(), "d")));
			File dir = new File(db.getWorkTree(), "e");
			assertTrue(dir.isDirectory());

			assertEquals(1, result.getConflicts().size());
			assertEquals(3, result.getConflicts().get("a")[0].length);

			assertEquals(RepositoryState.MERGING, db.getRepositoryState());
		}
	}

	@Test
	public void testMultipleCreations() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("a", "1\na\n3\n");
			git.add().addFilepattern("a").call();
			RevCommit initialCommit = git.commit().setMessage("initial").call();

			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");

			writeTrashFile("b", "1\nb(side)\n3\n");
			git.add().addFilepattern("b").call();
			RevCommit secondCommit = git.commit().setMessage("side").call();

			checkoutBranch("refs/heads/master");

			writeTrashFile("b", "1\nb(main)\n3\n");
			git.add().addFilepattern("b").call();
			git.commit().setMessage("main").call();

			MergeResult result = git.merge().include(secondCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();
			assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
		}
	}

	@Test
	public void testMultipleCreationsSameContent() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("a", "1\na\n3\n");
			git.add().addFilepattern("a").call();
			RevCommit initialCommit = git.commit().setMessage("initial").call();

			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");

			writeTrashFile("b", "1\nb(1)\n3\n");
			git.add().addFilepattern("b").call();
			RevCommit secondCommit = git.commit().setMessage("side").call();

			checkoutBranch("refs/heads/master");

			writeTrashFile("b", "1\nb(1)\n3\n");
			git.add().addFilepattern("b").call();
			git.commit().setMessage("main").call();

			MergeResult result = git.merge().include(secondCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();
			assertEquals(MergeStatus.MERGED, result.getMergeStatus());
			assertEquals("1\nb(1)\n3\n", read(new File(db.getWorkTree(), "b")));
			assertEquals("merge " + secondCommit.getId().getName()
					+ ": Merge made by resolve.", db
					.getReflogReader(Constants.HEAD)
					.getLastEntry().getComment());
			assertEquals("merge " + secondCommit.getId().getName()
					+ ": Merge made by resolve.", db
					.getReflogReader(db.getBranch())
					.getLastEntry().getComment());
		}
	}

	@Test
	public void testSuccessfulContentMerge() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("a", "1\na\n3\n");
			writeTrashFile("b", "1\nb\n3\n");
			writeTrashFile("c/c/c", "1\nc\n3\n");
			git.add().addFilepattern("a").addFilepattern("b")
					.addFilepattern("c/c/c").call();
			RevCommit initialCommit = git.commit().setMessage("initial").call();

			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");

			writeTrashFile("a", "1(side)\na\n3\n");
			writeTrashFile("b", "1\nb(side)\n3\n");
			git.add().addFilepattern("a").addFilepattern("b").call();
			RevCommit secondCommit = git.commit().setMessage("side").call();

			assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
			checkoutBranch("refs/heads/master");
			assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));

			writeTrashFile("a", "1\na\n3(main)\n");
			writeTrashFile("c/c/c", "1\nc(main)\n3\n");
			git.add().addFilepattern("a").addFilepattern("c/c/c").call();
			RevCommit thirdCommit = git.commit().setMessage("main").call();

			MergeResult result = git.merge().include(secondCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();
			assertEquals(MergeStatus.MERGED, result.getMergeStatus());

			assertEquals("1(side)\na\n3(main)\n", read(new File(db.getWorkTree(),
					"a")));
			assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
			assertEquals("1\nc(main)\n3\n", read(new File(db.getWorkTree(),
					"c/c/c")));

			assertEquals(null, result.getConflicts());

			assertEquals(2, result.getMergedCommits().length);
			assertEquals(thirdCommit, result.getMergedCommits()[0]);
			assertEquals(secondCommit, result.getMergedCommits()[1]);

			Iterator<RevCommit> it = git.log().call().iterator();
			RevCommit newHead = it.next();
			assertEquals(newHead, result.getNewHead());
			assertEquals(2, newHead.getParentCount());
			assertEquals(thirdCommit, newHead.getParent(0));
			assertEquals(secondCommit, newHead.getParent(1));
			assertEquals(
					"Merge commit '3fa334456d236a92db020289fe0bf481d91777b4'",
					newHead.getFullMessage());
			// @TODO fix me
			assertEquals(RepositoryState.SAFE, db.getRepositoryState());
			// test index state
		}
	}

	@Test
	public void testSuccessfulContentMergeNoCommit() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("a", "1\na\n3\n");
			writeTrashFile("b", "1\nb\n3\n");
			writeTrashFile("c/c/c", "1\nc\n3\n");
			git.add().addFilepattern("a").addFilepattern("b")
					.addFilepattern("c/c/c").call();
			RevCommit initialCommit = git.commit().setMessage("initial").call();

			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");

			writeTrashFile("a", "1(side)\na\n3\n");
			writeTrashFile("b", "1\nb(side)\n3\n");
			git.add().addFilepattern("a").addFilepattern("b").call();
			RevCommit secondCommit = git.commit().setMessage("side").call();

			assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
			checkoutBranch("refs/heads/master");
			assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));

			writeTrashFile("a", "1\na\n3(main)\n");
			writeTrashFile("c/c/c", "1\nc(main)\n3\n");
			git.add().addFilepattern("a").addFilepattern("c/c/c").call();
			RevCommit thirdCommit = git.commit().setMessage("main").call();

			MergeResult result = git.merge().include(secondCommit.getId())
					.setCommit(false)
					.setStrategy(MergeStrategy.RESOLVE).call();
			assertEquals(MergeStatus.MERGED_NOT_COMMITTED, result.getMergeStatus());
			assertEquals(db.exactRef(Constants.HEAD).getTarget().getObjectId(),
					thirdCommit.getId());

			assertEquals("1(side)\na\n3(main)\n", read(new File(db.getWorkTree(),
					"a")));
			assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
			assertEquals("1\nc(main)\n3\n",
					read(new File(db.getWorkTree(), "c/c/c")));

			assertEquals(null, result.getConflicts());

			assertEquals(2, result.getMergedCommits().length);
			assertEquals(thirdCommit, result.getMergedCommits()[0]);
			assertEquals(secondCommit, result.getMergedCommits()[1]);
			assertNull(result.getNewHead());
			assertEquals(RepositoryState.MERGING_RESOLVED, db.getRepositoryState());
		}
	}

	@Test
	public void testSuccessfulContentMergeAndDirtyworkingTree()
			throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("a", "1\na\n3\n");
			writeTrashFile("b", "1\nb\n3\n");
			writeTrashFile("d", "1\nd\n3\n");
			writeTrashFile("c/c/c", "1\nc\n3\n");
			git.add().addFilepattern("a").addFilepattern("b")
					.addFilepattern("c/c/c").addFilepattern("d").call();
			RevCommit initialCommit = git.commit().setMessage("initial").call();

			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");

			writeTrashFile("a", "1(side)\na\n3\n");
			writeTrashFile("b", "1\nb(side)\n3\n");
			git.add().addFilepattern("a").addFilepattern("b").call();
			RevCommit secondCommit = git.commit().setMessage("side").call();

			assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
			checkoutBranch("refs/heads/master");
			assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));

			writeTrashFile("a", "1\na\n3(main)\n");
			writeTrashFile("c/c/c", "1\nc(main)\n3\n");
			git.add().addFilepattern("a").addFilepattern("c/c/c").call();
			RevCommit thirdCommit = git.commit().setMessage("main").call();

			writeTrashFile("d", "--- dirty ---");
			MergeResult result = git.merge().include(secondCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();
			assertEquals(MergeStatus.MERGED, result.getMergeStatus());

			assertEquals("1(side)\na\n3(main)\n", read(new File(db.getWorkTree(),
					"a")));
			assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
			assertEquals("1\nc(main)\n3\n", read(new File(db.getWorkTree(),
					"c/c/c")));
			assertEquals("--- dirty ---", read(new File(db.getWorkTree(), "d")));

			assertEquals(null, result.getConflicts());

			assertEquals(2, result.getMergedCommits().length);
			assertEquals(thirdCommit, result.getMergedCommits()[0]);
			assertEquals(secondCommit, result.getMergedCommits()[1]);

			Iterator<RevCommit> it = git.log().call().iterator();
			RevCommit newHead = it.next();
			assertEquals(newHead, result.getNewHead());
			assertEquals(2, newHead.getParentCount());
			assertEquals(thirdCommit, newHead.getParent(0));
			assertEquals(secondCommit, newHead.getParent(1));
			assertEquals(
					"Merge commit '064d54d98a4cdb0fed1802a21c656bfda67fe879'",
					newHead.getFullMessage());

			assertEquals(RepositoryState.SAFE, db.getRepositoryState());
		}
	}

	@Test
	public void testSingleDeletion() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("a", "1\na\n3\n");
			writeTrashFile("b", "1\nb\n3\n");
			writeTrashFile("d", "1\nd\n3\n");
			writeTrashFile("c/c/c", "1\nc\n3\n");
			git.add().addFilepattern("a").addFilepattern("b")
					.addFilepattern("c/c/c").addFilepattern("d").call();
			RevCommit initialCommit = git.commit().setMessage("initial").call();

			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");

			assertTrue(new File(db.getWorkTree(), "b").delete());
			git.add().addFilepattern("b").setUpdate(true).call();
			RevCommit secondCommit = git.commit().setMessage("side").call();

			assertFalse(new File(db.getWorkTree(), "b").exists());
			checkoutBranch("refs/heads/master");
			assertTrue(new File(db.getWorkTree(), "b").exists());

			writeTrashFile("a", "1\na\n3(main)\n");
			writeTrashFile("c/c/c", "1\nc(main)\n3\n");
			git.add().addFilepattern("a").addFilepattern("c/c/c").call();
			RevCommit thirdCommit = git.commit().setMessage("main").call();

			// We are merging a deletion into our branch
			MergeResult result = git.merge().include(secondCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();
			assertEquals(MergeStatus.MERGED, result.getMergeStatus());

			assertEquals("1\na\n3(main)\n", read(new File(db.getWorkTree(), "a")));
			assertFalse(new File(db.getWorkTree(), "b").exists());
			assertEquals("1\nc(main)\n3\n",
					read(new File(db.getWorkTree(), "c/c/c")));
			assertEquals("1\nd\n3\n", read(new File(db.getWorkTree(), "d")));

			// Do the opposite, be on a branch where we have deleted a file and
			// merge in a old commit where this file was not deleted
			checkoutBranch("refs/heads/side");
			assertFalse(new File(db.getWorkTree(), "b").exists());

			result = git.merge().include(thirdCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();
			assertEquals(MergeStatus.MERGED, result.getMergeStatus());

			assertEquals("1\na\n3(main)\n", read(new File(db.getWorkTree(), "a")));
			assertFalse(new File(db.getWorkTree(), "b").exists());
			assertEquals("1\nc(main)\n3\n",
					read(new File(db.getWorkTree(), "c/c/c")));
			assertEquals("1\nd\n3\n", read(new File(db.getWorkTree(), "d")));
		}
	}

	@Test
	public void testMultipleDeletions() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("a", "1\na\n3\n");
			git.add().addFilepattern("a").call();
			RevCommit initialCommit = git.commit().setMessage("initial").call();

			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");

			assertTrue(new File(db.getWorkTree(), "a").delete());
			git.add().addFilepattern("a").setUpdate(true).call();
			RevCommit secondCommit = git.commit().setMessage("side").call();

			assertFalse(new File(db.getWorkTree(), "a").exists());
			checkoutBranch("refs/heads/master");
			assertTrue(new File(db.getWorkTree(), "a").exists());

			assertTrue(new File(db.getWorkTree(), "a").delete());
			git.add().addFilepattern("a").setUpdate(true).call();
			git.commit().setMessage("main").call();

			// We are merging a deletion into our branch
			MergeResult result = git.merge().include(secondCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();
			assertEquals(MergeStatus.MERGED, result.getMergeStatus());
		}
	}

	@Test
	public void testDeletionAndConflict() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("a", "1\na\n3\n");
			writeTrashFile("b", "1\nb\n3\n");
			writeTrashFile("d", "1\nd\n3\n");
			writeTrashFile("c/c/c", "1\nc\n3\n");
			git.add().addFilepattern("a").addFilepattern("b")
					.addFilepattern("c/c/c").addFilepattern("d").call();
			RevCommit initialCommit = git.commit().setMessage("initial").call();

			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");

			assertTrue(new File(db.getWorkTree(), "b").delete());
			writeTrashFile("a", "1\na\n3(side)\n");
			git.add().addFilepattern("b").setUpdate(true).call();
			git.add().addFilepattern("a").setUpdate(true).call();
			RevCommit secondCommit = git.commit().setMessage("side").call();

			assertFalse(new File(db.getWorkTree(), "b").exists());
			checkoutBranch("refs/heads/master");
			assertTrue(new File(db.getWorkTree(), "b").exists());

			writeTrashFile("a", "1\na\n3(main)\n");
			writeTrashFile("c/c/c", "1\nc(main)\n3\n");
			git.add().addFilepattern("a").addFilepattern("c/c/c").call();
			git.commit().setMessage("main").call();

			// We are merging a deletion into our branch
			MergeResult result = git.merge().include(secondCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();
			assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());

			assertEquals(
					"1\na\n<<<<<<< HEAD\n3(main)\n=======\n3(side)\n>>>>>>> 54ffed45d62d252715fc20e41da92d44c48fb0ff\n",
					read(new File(db.getWorkTree(), "a")));
			assertFalse(new File(db.getWorkTree(), "b").exists());
			assertEquals("1\nc(main)\n3\n",
					read(new File(db.getWorkTree(), "c/c/c")));
			assertEquals("1\nd\n3\n", read(new File(db.getWorkTree(), "d")));
		}
	}

	@Test
	public void testDeletionOnMasterConflict() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("a", "1\na\n3\n");
			writeTrashFile("b", "1\nb\n3\n");
			git.add().addFilepattern("a").addFilepattern("b").call();
			RevCommit initialCommit = git.commit().setMessage("initial").call();

			// create side branch and modify "a"
			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");
			writeTrashFile("a", "1\na(side)\n3\n");
			git.add().addFilepattern("a").call();
			RevCommit secondCommit = git.commit().setMessage("side").call();

			// delete a on master to generate conflict
			checkoutBranch("refs/heads/master");
			git.rm().addFilepattern("a").call();
			git.commit().setMessage("main").call();

			// merge side with master
			MergeResult result = git.merge().include(secondCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();
			assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());

			// result should be 'a' conflicting with workspace content from side
			assertTrue(new File(db.getWorkTree(), "a").exists());
			assertEquals("1\na(side)\n3\n", read(new File(db.getWorkTree(), "a")));
			assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));
		}
	}

	@Test
	public void testDeletionOnSideConflict() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("a", "1\na\n3\n");
			writeTrashFile("b", "1\nb\n3\n");
			git.add().addFilepattern("a").addFilepattern("b").call();
			RevCommit initialCommit = git.commit().setMessage("initial").call();

			// create side branch and delete "a"
			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");
			git.rm().addFilepattern("a").call();
			RevCommit secondCommit = git.commit().setMessage("side").call();

			// update a on master to generate conflict
			checkoutBranch("refs/heads/master");
			writeTrashFile("a", "1\na(main)\n3\n");
			git.add().addFilepattern("a").call();
			git.commit().setMessage("main").call();

			// merge side with master
			MergeResult result = git.merge().include(secondCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();
			assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());

			assertTrue(new File(db.getWorkTree(), "a").exists());
			assertEquals("1\na(main)\n3\n", read(new File(db.getWorkTree(), "a")));
			assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));

			assertEquals(1, result.getConflicts().size());
			assertEquals(3, result.getConflicts().get("a")[0].length);
		}
	}

	@Test
	public void testModifiedAndRenamed() throws Exception {
		// this test is essentially the same as testDeletionOnSideConflict,
		// however if once rename support is added this test should result in a
		// successful merge instead of a conflict
		try (Git git = new Git(db)) {
			writeTrashFile("x", "add x");
			git.add().addFilepattern("x").call();
			RevCommit initial = git.commit().setMessage("add x").call();

			createBranch(initial, "refs/heads/d1");
			createBranch(initial, "refs/heads/d2");

			// rename x to y on d1
			checkoutBranch("refs/heads/d1");
			new File(db.getWorkTree(), "x")
					.renameTo(new File(db.getWorkTree(), "y"));
			git.rm().addFilepattern("x").call();
			git.add().addFilepattern("y").call();
			RevCommit d1Commit = git.commit().setMessage("d1 rename x -> y").call();

			checkoutBranch("refs/heads/d2");
			writeTrashFile("x", "d2 change");
			git.add().addFilepattern("x").call();
			RevCommit d2Commit = git.commit().setMessage("d2 change in x").call();

			checkoutBranch("refs/heads/master");
			MergeResult d1Merge = git.merge().include(d1Commit).call();
			assertEquals(MergeResult.MergeStatus.FAST_FORWARD,
					d1Merge.getMergeStatus());

			MergeResult d2Merge = git.merge().include(d2Commit).call();
			assertEquals(MergeResult.MergeStatus.CONFLICTING,
					d2Merge.getMergeStatus());
			assertEquals(1, d2Merge.getConflicts().size());
			assertEquals(3, d2Merge.getConflicts().get("x")[0].length);
		}
	}

	@Test
	public void testMergeFailingWithDirtyWorkingTree() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("a", "1\na\n3\n");
			writeTrashFile("b", "1\nb\n3\n");
			git.add().addFilepattern("a").addFilepattern("b").call();
			RevCommit initialCommit = git.commit().setMessage("initial").call();

			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");

			writeTrashFile("a", "1(side)\na\n3\n");
			writeTrashFile("b", "1\nb(side)\n3\n");
			git.add().addFilepattern("a").addFilepattern("b").call();
			RevCommit secondCommit = git.commit().setMessage("side").call();

			assertEquals("1\nb(side)\n3\n", read(new File(db.getWorkTree(), "b")));
			checkoutBranch("refs/heads/master");
			assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));

			writeTrashFile("a", "1\na\n3(main)\n");
			git.add().addFilepattern("a").call();
			git.commit().setMessage("main").call();

			writeTrashFile("a", "--- dirty ---");
			MergeResult result = git.merge().include(secondCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();

			assertEquals(MergeStatus.FAILED, result.getMergeStatus());

			assertEquals("--- dirty ---", read(new File(db.getWorkTree(), "a")));
			assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));

			assertEquals(null, result.getConflicts());

			assertEquals(RepositoryState.SAFE, db.getRepositoryState());
		}
	}

	@Test
	public void testMergeConflictFileFolder() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("a", "1\na\n3\n");
			writeTrashFile("b", "1\nb\n3\n");
			git.add().addFilepattern("a").addFilepattern("b").call();
			RevCommit initialCommit = git.commit().setMessage("initial").call();

			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");

			writeTrashFile("c/c/c", "1\nc(side)\n3\n");
			writeTrashFile("d", "1\nd(side)\n3\n");
			git.add().addFilepattern("c/c/c").addFilepattern("d").call();
			RevCommit secondCommit = git.commit().setMessage("side").call();

			checkoutBranch("refs/heads/master");

			writeTrashFile("c", "1\nc(main)\n3\n");
			writeTrashFile("d/d/d", "1\nd(main)\n3\n");
			git.add().addFilepattern("c").addFilepattern("d/d/d").call();
			git.commit().setMessage("main").call();

			MergeResult result = git.merge().include(secondCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();

			assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());

			assertEquals("1\na\n3\n", read(new File(db.getWorkTree(), "a")));
			assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b")));
			assertEquals("1\nc(main)\n3\n", read(new File(db.getWorkTree(), "c")));
			assertEquals("1\nd(main)\n3\n", read(new File(db.getWorkTree(), "d/d/d")));

			assertEquals(null, result.getConflicts());

			assertEquals(RepositoryState.MERGING, db.getRepositoryState());
		}
	}

	@Test
	public void testSuccessfulMergeFailsDueToDirtyIndex() throws Exception {
		try (Git git = new Git(db)) {
			File fileA = writeTrashFile("a", "a");
			RevCommit initialCommit = addAllAndCommit(git);

			// switch branch
			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");
			// modify file a
			write(fileA, "a(side)");
			writeTrashFile("b", "b");
			RevCommit sideCommit = addAllAndCommit(git);

			// switch branch
			checkoutBranch("refs/heads/master");
			writeTrashFile("c", "c");
			addAllAndCommit(git);

			// modify and add file a
			write(fileA, "a(modified)");
			git.add().addFilepattern("a").call();
			// do not commit

			// get current index state
			String indexState = indexState(CONTENT);

			// merge
			MergeResult result = git.merge().include(sideCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();

			checkMergeFailedResult(result, MergeFailureReason.DIRTY_INDEX,
					indexState, fileA);
		}
	}

	@Test
	public void testConflictingMergeFailsDueToDirtyIndex() throws Exception {
		try (Git git = new Git(db)) {
			File fileA = writeTrashFile("a", "a");
			RevCommit initialCommit = addAllAndCommit(git);

			// switch branch
			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");
			// modify file a
			write(fileA, "a(side)");
			writeTrashFile("b", "b");
			RevCommit sideCommit = addAllAndCommit(git);

			// switch branch
			checkoutBranch("refs/heads/master");
			// modify file a - this will cause a conflict during merge
			write(fileA, "a(master)");
			writeTrashFile("c", "c");
			addAllAndCommit(git);

			// modify and add file a
			write(fileA, "a(modified)");
			git.add().addFilepattern("a").call();
			// do not commit

			// get current index state
			String indexState = indexState(CONTENT);

			// merge
			MergeResult result = git.merge().include(sideCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();

			checkMergeFailedResult(result, MergeFailureReason.DIRTY_INDEX,
					indexState, fileA);
		}
	}

	@Test
	public void testSuccessfulMergeFailsDueToDirtyWorktree() throws Exception {
		try (Git git = new Git(db)) {
			File fileA = writeTrashFile("a", "a");
			RevCommit initialCommit = addAllAndCommit(git);

			// switch branch
			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");
			// modify file a
			write(fileA, "a(side)");
			writeTrashFile("b", "b");
			RevCommit sideCommit = addAllAndCommit(git);

			// switch branch
			checkoutBranch("refs/heads/master");
			writeTrashFile("c", "c");
			addAllAndCommit(git);

			// modify file a
			write(fileA, "a(modified)");
			// do not add and commit

			// get current index state
			String indexState = indexState(CONTENT);

			// merge
			MergeResult result = git.merge().include(sideCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();

			checkMergeFailedResult(result, MergeFailureReason.DIRTY_WORKTREE,
					indexState, fileA);
		}
	}

	@Test
	public void testConflictingMergeFailsDueToDirtyWorktree() throws Exception {
		try (Git git = new Git(db)) {
			File fileA = writeTrashFile("a", "a");
			RevCommit initialCommit = addAllAndCommit(git);

			// switch branch
			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");
			// modify file a
			write(fileA, "a(side)");
			writeTrashFile("b", "b");
			RevCommit sideCommit = addAllAndCommit(git);

			// switch branch
			checkoutBranch("refs/heads/master");
			// modify file a - this will cause a conflict during merge
			write(fileA, "a(master)");
			writeTrashFile("c", "c");
			addAllAndCommit(git);

			// modify file a
			write(fileA, "a(modified)");
			// do not add and commit

			// get current index state
			String indexState = indexState(CONTENT);

			// merge
			MergeResult result = git.merge().include(sideCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();

			checkMergeFailedResult(result, MergeFailureReason.DIRTY_WORKTREE,
					indexState, fileA);
		}
	}

	@Test
	public void testMergeRemovingFolders() throws Exception {
		File folder1 = new File(db.getWorkTree(), "folder1");
		File folder2 = new File(db.getWorkTree(), "folder2");
		FileUtils.mkdir(folder1);
		FileUtils.mkdir(folder2);
		File file = new File(folder1, "file1.txt");
		write(file, "folder1--file1.txt");
		file = new File(folder1, "file2.txt");
		write(file, "folder1--file2.txt");
		file = new File(folder2, "file1.txt");
		write(file, "folder--file1.txt");
		file = new File(folder2, "file2.txt");
		write(file, "folder2--file2.txt");

		try (Git git = new Git(db)) {
			git.add().addFilepattern(folder1.getName())
					.addFilepattern(folder2.getName()).call();
			RevCommit commit1 = git.commit().setMessage("adding folders").call();

			recursiveDelete(folder1);
			recursiveDelete(folder2);
			git.rm().addFilepattern("folder1/file1.txt")
					.addFilepattern("folder1/file2.txt")
					.addFilepattern("folder2/file1.txt")
					.addFilepattern("folder2/file2.txt").call();
			RevCommit commit2 = git.commit()
					.setMessage("removing folders on 'branch'").call();

			git.checkout().setName(commit1.name()).call();

			MergeResult result = git.merge().include(commit2.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();
			assertEquals(MergeResult.MergeStatus.FAST_FORWARD,
					result.getMergeStatus());
			assertEquals(commit2, result.getNewHead());
			assertFalse(folder1.exists());
			assertFalse(folder2.exists());
		}
	}

	@Test
	public void testMergeRemovingFoldersWithoutFastForward() throws Exception {
		File folder1 = new File(db.getWorkTree(), "folder1");
		File folder2 = new File(db.getWorkTree(), "folder2");
		FileUtils.mkdir(folder1);
		FileUtils.mkdir(folder2);
		File file = new File(folder1, "file1.txt");
		write(file, "folder1--file1.txt");
		file = new File(folder1, "file2.txt");
		write(file, "folder1--file2.txt");
		file = new File(folder2, "file1.txt");
		write(file, "folder--file1.txt");
		file = new File(folder2, "file2.txt");
		write(file, "folder2--file2.txt");

		try (Git git = new Git(db)) {
			git.add().addFilepattern(folder1.getName())
					.addFilepattern(folder2.getName()).call();
			RevCommit base = git.commit().setMessage("adding folders").call();

			recursiveDelete(folder1);
			recursiveDelete(folder2);
			git.rm().addFilepattern("folder1/file1.txt")
					.addFilepattern("folder1/file2.txt")
					.addFilepattern("folder2/file1.txt")
					.addFilepattern("folder2/file2.txt").call();
			RevCommit other = git.commit()
					.setMessage("removing folders on 'branch'").call();

			git.checkout().setName(base.name()).call();

			file = new File(folder2, "file3.txt");
			write(file, "folder2--file3.txt");

			git.add().addFilepattern(folder2.getName()).call();
			git.commit().setMessage("adding another file").call();

			MergeResult result = git.merge().include(other.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();

			assertEquals(MergeResult.MergeStatus.MERGED,
					result.getMergeStatus());
			assertFalse(folder1.exists());
		}
	}

	@Test
	public void testFileModeMerge() throws Exception {
		// Only Java6
		assumeTrue(FS.DETECTED.supportsExecute());
		try (Git git = new Git(db)) {
			writeTrashFile("mergeableMode", "a");
			setExecutable(git, "mergeableMode", false);
			writeTrashFile("conflictingModeWithBase", "a");
			setExecutable(git, "conflictingModeWithBase", false);
			RevCommit initialCommit = addAllAndCommit(git);

			// switch branch
			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");
			setExecutable(git, "mergeableMode", true);
			writeTrashFile("conflictingModeNoBase", "b");
			setExecutable(git, "conflictingModeNoBase", true);
			RevCommit sideCommit = addAllAndCommit(git);

			// switch branch
			createBranch(initialCommit, "refs/heads/side2");
			checkoutBranch("refs/heads/side2");
			setExecutable(git, "mergeableMode", false);
			assertFalse(new File(git.getRepository().getWorkTree(),
					"conflictingModeNoBase").exists());
			writeTrashFile("conflictingModeNoBase", "b");
			setExecutable(git, "conflictingModeNoBase", false);
			addAllAndCommit(git);

			// merge
			MergeResult result = git.merge().include(sideCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();
			assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
			assertTrue(canExecute(git, "mergeableMode"));
			assertFalse(canExecute(git, "conflictingModeNoBase"));
		}
	}

	@Test
	public void testFileModeMergeWithDirtyWorkTree() throws Exception {
		// Only Java6 (or set x bit in index)
		assumeTrue(FS.DETECTED.supportsExecute());

		try (Git git = new Git(db)) {
			writeTrashFile("mergeableButDirty", "a");
			setExecutable(git, "mergeableButDirty", false);
			RevCommit initialCommit = addAllAndCommit(git);

			// switch branch
			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");
			setExecutable(git, "mergeableButDirty", true);
			RevCommit sideCommit = addAllAndCommit(git);

			// switch branch
			createBranch(initialCommit, "refs/heads/side2");
			checkoutBranch("refs/heads/side2");
			setExecutable(git, "mergeableButDirty", false);
			addAllAndCommit(git);

			writeTrashFile("mergeableButDirty", "b");

			// merge
			MergeResult result = git.merge().include(sideCommit.getId())
					.setStrategy(MergeStrategy.RESOLVE).call();
			assertEquals(MergeStatus.FAILED, result.getMergeStatus());
			assertFalse(canExecute(git, "mergeableButDirty"));
		}
	}

	@Test
	public void testSquashFastForward() 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();
			RevCommit second = git.commit().setMessage("second commit").call();
			assertTrue(new File(db.getWorkTree(), "file2").exists());

			writeTrashFile("file3", "file3");
			git.add().addFilepattern("file3").call();
			RevCommit third = git.commit().setMessage("third commit").call();
			assertTrue(new File(db.getWorkTree(), "file3").exists());

			checkoutBranch("refs/heads/master");
			assertTrue(new File(db.getWorkTree(), "file1").exists());
			assertFalse(new File(db.getWorkTree(), "file2").exists());
			assertFalse(new File(db.getWorkTree(), "file3").exists());

			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());
			assertTrue(new File(db.getWorkTree(), "file3").exists());
			assertEquals(MergeResult.MergeStatus.FAST_FORWARD_SQUASHED,
					result.getMergeStatus());
			assertEquals(first, result.getNewHead()); // HEAD didn't move
			assertEquals(first, db.resolve(Constants.HEAD + "^{commit}"));

			assertEquals(
					"Squashed commit of the following:\n\ncommit "
							+ third.getName()
							+ "\nAuthor: "
							+ third.getAuthorIdent().getName()
							+ " <"
							+ third.getAuthorIdent().getEmailAddress()
							+ ">\nDate:   "
							+ dateFormatter.formatDate(third
									.getAuthorIdent())
							+ "\n\n\tthird commit\n\ncommit "
							+ second.getName()
							+ "\nAuthor: "
							+ second.getAuthorIdent().getName()
							+ " <"
							+ second.getAuthorIdent().getEmailAddress()
							+ ">\nDate:   "
							+ dateFormatter.formatDate(second
									.getAuthorIdent()) + "\n\n\tsecond commit\n",
					db.readSquashCommitMsg());
			assertNull(db.readMergeCommitMsg());

			Status stat = git.status().call();
			assertEquals(Sets.of("file2", "file3"), stat.getAdded());
		}
	}

	@Test
	public void testSquashMerge() 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");

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

			checkoutBranch("refs/heads/branch1");

			writeTrashFile("file3", "file3");
			git.add().addFilepattern("file3").call();
			RevCommit third = git.commit().setMessage("third commit").call();
			assertTrue(new File(db.getWorkTree(), "file3").exists());

			checkoutBranch("refs/heads/master");
			assertTrue(new File(db.getWorkTree(), "file1").exists());
			assertTrue(new File(db.getWorkTree(), "file2").exists());
			assertFalse(new File(db.getWorkTree(), "file3").exists());

			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());
			assertTrue(new File(db.getWorkTree(), "file3").exists());
			assertEquals(MergeResult.MergeStatus.MERGED_SQUASHED,
					result.getMergeStatus());
			assertEquals(second, result.getNewHead()); // HEAD didn't move
			assertEquals(second, db.resolve(Constants.HEAD + "^{commit}"));

			assertEquals(
					"Squashed commit of the following:\n\ncommit "
							+ third.getName()
							+ "\nAuthor: "
							+ third.getAuthorIdent().getName()
							+ " <"
							+ third.getAuthorIdent().getEmailAddress()
							+ ">\nDate:   "
							+ dateFormatter.formatDate(third
									.getAuthorIdent()) + "\n\n\tthird commit\n",
					db.readSquashCommitMsg());
			assertNull(db.readMergeCommitMsg());

			Status stat = git.status().call();
			assertEquals(Sets.of("file3"), stat.getAdded());
		}
	}

	@Test
	public void testSquashMergeConflict() 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");

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

			checkoutBranch("refs/heads/branch1");

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

			checkoutBranch("refs/heads/master");
			assertTrue(new File(db.getWorkTree(), "file1").exists());
			assertTrue(new File(db.getWorkTree(), "file2").exists());

			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.CONFLICTING,
					result.getMergeStatus());
			assertNull(result.getNewHead());
			assertEquals(second, db.resolve(Constants.HEAD + "^{commit}"));

			assertEquals(
					"Squashed commit of the following:\n\ncommit "
							+ third.getName()
							+ "\nAuthor: "
							+ third.getAuthorIdent().getName()
							+ " <"
							+ third.getAuthorIdent().getEmailAddress()
							+ ">\nDate:   "
							+ dateFormatter.formatDate(third
									.getAuthorIdent()) + "\n\n\tthird commit\n",
					db.readSquashCommitMsg());
			assertEquals("\nConflicts:\n\tfile2\n", db.readMergeCommitMsg());

			Status stat = git.status().call();
			assertEquals(Sets.of("file2"), stat.getConflicting());
		}
	}

	@Test
	public void testFastForwardOnly() throws Exception {
		try (Git git = new Git(db)) {
			RevCommit initialCommit = git.commit().setMessage("initial commit")
					.call();
			createBranch(initialCommit, "refs/heads/branch1");
			git.commit().setMessage("second commit").call();
			checkoutBranch("refs/heads/branch1");

			MergeCommand merge = git.merge();
			merge.setFastForward(FastForwardMode.FF_ONLY);
			merge.include(db.exactRef(R_HEADS + MASTER));
			MergeResult result = merge.call();

			assertEquals(MergeStatus.FAST_FORWARD, result.getMergeStatus());
		}
	}

	@Test
	public void testNoFastForward() throws Exception {
		try (Git git = new Git(db)) {
			RevCommit initialCommit = git.commit().setMessage("initial commit")
					.call();
			createBranch(initialCommit, "refs/heads/branch1");
			git.commit().setMessage("second commit").call();
			checkoutBranch("refs/heads/branch1");

			MergeCommand merge = git.merge();
			merge.setFastForward(FastForwardMode.NO_FF);
			merge.include(db.exactRef(R_HEADS + MASTER));
			MergeResult result = merge.call();

			assertEquals(MergeStatus.MERGED, result.getMergeStatus());
		}
	}

	@Test
	public void testNoFastForwardNoCommit() throws Exception {
		// given
		try (Git git = new Git(db)) {
			RevCommit initialCommit = git.commit().setMessage("initial commit")
					.call();
			createBranch(initialCommit, "refs/heads/branch1");
			RevCommit secondCommit = git.commit().setMessage("second commit")
					.call();
			checkoutBranch("refs/heads/branch1");

			// when
			MergeCommand merge = git.merge();
			merge.setFastForward(FastForwardMode.NO_FF);
			merge.include(db.exactRef(R_HEADS + MASTER));
			merge.setCommit(false);
			MergeResult result = merge.call();

			// then
			assertEquals(MergeStatus.MERGED_NOT_COMMITTED, result.getMergeStatus());
			assertEquals(2, result.getMergedCommits().length);
			assertEquals(initialCommit, result.getMergedCommits()[0]);
			assertEquals(secondCommit, result.getMergedCommits()[1]);
			assertNull(result.getNewHead());
			assertEquals(RepositoryState.MERGING_RESOLVED, db.getRepositoryState());
		}
	}

	@Test
	public void testFastForwardOnlyNotPossible() throws Exception {
		try (Git git = new Git(db)) {
			RevCommit initialCommit = git.commit().setMessage("initial commit")
					.call();
			createBranch(initialCommit, "refs/heads/branch1");
			git.commit().setMessage("second commit").call();
			checkoutBranch("refs/heads/branch1");
			writeTrashFile("file1", "branch1");
			git.add().addFilepattern("file").call();
			git.commit().setMessage("second commit on branch1").call();
			MergeCommand merge = git.merge();
			merge.setFastForward(FastForwardMode.FF_ONLY);
			merge.include(db.exactRef(R_HEADS + MASTER));
			MergeResult result = merge.call();

			assertEquals(MergeStatus.ABORTED, result.getMergeStatus());
		}
	}

	@Test
	public void testRecursiveMergeWithConflict() throws Exception {
		try (TestRepository<Repository> db_t = new TestRepository<>(db)) {
			BranchBuilder master = db_t.branch("master");
			RevCommit m0 = master.commit()
					.add("f", "1\n2\n3\n4\n5\n6\n7\n8\n9\n").message("m0")
					.create();
			RevCommit m1 = master.commit()
					.add("f", "1-master\n2\n3\n4\n5\n6\n7\n8\n9\n")
					.message("m1").create();
			db_t.getRevWalk().parseCommit(m1);

			BranchBuilder side = db_t.branch("side");
			RevCommit s1 = side.commit().parent(m0)
					.add("f", "1\n2\n3\n4\n5\n6\n7\n8\n9-side\n").message("s1")
					.create();
			RevCommit s2 = side.commit().parent(m1)
					.add("f",
							"1-master\n2\n3\n4\n5\n6\n7-res(side)\n8\n9-side\n")
					.message("s2(merge)").create();
			master.commit().parent(s1)
					.add("f",
							"1-master\n2\n3\n4\n5\n6\n7-conflict\n8\n9-side\n")
					.message("m2(merge)").create();

			Git git = Git.wrap(db);
			git.checkout().setName("master").call();

			MergeResult result = git.merge()
					.setStrategy(MergeStrategy.RECURSIVE).include("side", s2)
					.call();
			assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
		}
	}

	private Ref prepareSuccessfulMerge(Git git) throws Exception {
		writeTrashFile("a", "1\na\n3\n");
		git.add().addFilepattern("a").call();
		RevCommit initialCommit = git.commit().setMessage("initial").call();

		createBranch(initialCommit, "refs/heads/side");
		checkoutBranch("refs/heads/side");

		writeTrashFile("b", "1\nb\n3\n");
		git.add().addFilepattern("b").call();
		git.commit().setMessage("side").call();

		checkoutBranch("refs/heads/master");

		writeTrashFile("c", "1\nc\n3\n");
		git.add().addFilepattern("c").call();
		git.commit().setMessage("main").call();

		return db.exactRef("refs/heads/side");
	}

	@Test
	public void testMergeWithMessageOption() throws Exception {
		try (Git git = new Git(db)) {
			Ref sideBranch = prepareSuccessfulMerge(git);

			git.merge().include(sideBranch).setStrategy(MergeStrategy.RESOLVE)
					.setMessage("user message").call();

			assertNull(db.readMergeCommitMsg());

			Iterator<RevCommit> it = git.log().call().iterator();
			RevCommit newHead = it.next();
			assertEquals("user message", newHead.getFullMessage());
		}
	}

	@Test
	public void testMergeWithChangeId() throws Exception {
		try (Git git = new Git(db)) {
			Ref sideBranch = prepareSuccessfulMerge(git);

			git.merge().include(sideBranch).setStrategy(MergeStrategy.RESOLVE)
					.setInsertChangeId(true).call();

			assertNull(db.readMergeCommitMsg());

			Iterator<RevCommit> it = git.log().call().iterator();
			RevCommit newHead = it.next();
			String commitMessage = newHead.getFullMessage();
			assertTrue(Pattern.compile("\nChange-Id: I[0-9a-fA-F]{40}\n")
					.matcher(commitMessage).find());
		}
	}

	@Test
	public void testMergeWithMessageAndChangeId() throws Exception {
		try (Git git = new Git(db)) {
			Ref sideBranch = prepareSuccessfulMerge(git);

			git.merge().include(sideBranch).setStrategy(MergeStrategy.RESOLVE)
					.setMessage("user message").setInsertChangeId(true).call();

			assertNull(db.readMergeCommitMsg());

			Iterator<RevCommit> it = git.log().call().iterator();
			RevCommit newHead = it.next();
			String commitMessage = newHead.getFullMessage();
			assertTrue(commitMessage.startsWith("user message\n\n"));
			assertTrue(Pattern.compile("\nChange-Id: I[0-9a-fA-F]{40}\n")
					.matcher(commitMessage).find());
		}
	}

	@Test
	public void testMergeConflictWithMessageOption() throws Exception {
		try (Git git = new Git(db)) {
			writeTrashFile("a", "1\na\n3\n");
			git.add().addFilepattern("a").call();
			RevCommit initialCommit = git.commit().setMessage("initial").call();

			createBranch(initialCommit, "refs/heads/side");
			checkoutBranch("refs/heads/side");

			writeTrashFile("a", "1\na(side)\n3\n");
			git.add().addFilepattern("a").call();
			git.commit().setMessage("side").call();

			checkoutBranch("refs/heads/master");

			writeTrashFile("a", "1\na(main)\n3\n");
			git.add().addFilepattern("a").call();
			git.commit().setMessage("main").call();

			Ref sideBranch = db.exactRef("refs/heads/side");

			git.merge().include(sideBranch).setStrategy(MergeStrategy.RESOLVE)
					.setMessage("user message").call();

			assertEquals("user message\n\nConflicts:\n\ta\n",
					db.readMergeCommitMsg());
		}
	}

	private static void setExecutable(Git git, String path, boolean executable) {
		FS.DETECTED.setExecute(
				new File(git.getRepository().getWorkTree(), path), executable);
	}

	private static boolean canExecute(Git git, String path) {
		return FS.DETECTED.canExecute(new File(git.getRepository()
				.getWorkTree(), path));
	}

	private static RevCommit addAllAndCommit(Git git) throws Exception {
		git.add().addFilepattern(".").call();
		return git.commit().setMessage("message").call();
	}

	private void checkMergeFailedResult(final MergeResult result,
			final MergeFailureReason reason,
			final String indexState, final File fileA) throws Exception {
		assertEquals(MergeStatus.FAILED, result.getMergeStatus());
		assertEquals(reason, result.getFailingPaths().get("a"));
		assertEquals("a(modified)", read(fileA));
		assertFalse(new File(db.getWorkTree(), "b").exists());
		assertEquals("c", read(new File(db.getWorkTree(), "c")));
		assertEquals(indexState, indexState(CONTENT));
		assertEquals(null, result.getConflicts());
		assertEquals(RepositoryState.SAFE, db.getRepositoryState());
	}
}
