/*
 * Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com>
 * Copyright (C) 2011, Matthias Sohn <matthias.sohn@sap.com> and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
package org.eclipse.jgit.api;

import static java.time.Instant.EPOCH;
import static org.eclipse.jgit.lib.Constants.MASTER;
import static org.eclipse.jgit.lib.Constants.R_HEADS;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
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 java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.attribute.FileTime;
import java.time.Instant;

import org.eclipse.jgit.api.CheckoutResult.Status;
import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
import org.eclipse.jgit.api.errors.CheckoutConflictException;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRefNameException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
import org.eclipse.jgit.api.errors.RefNotFoundException;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.junit.JGitTestUtil;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.junit.time.TimeUtil;
import org.eclipse.jgit.lfs.BuiltinLFS;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.Sets;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils;
import org.eclipse.jgit.util.SystemReader;
import org.junit.Before;
import org.junit.Test;

public class CheckoutCommandTest extends RepositoryTestCase {
	private Git git;

	RevCommit initialCommit;

	RevCommit secondCommit;

	@Override
	@Before
	public void setUp() throws Exception {
		BuiltinLFS.register();
		super.setUp();
		git = new Git(db);
		// commit something
		writeTrashFile("Test.txt", "Hello world");
		git.add().addFilepattern("Test.txt").call();
		initialCommit = git.commit().setMessage("Initial commit").call();

		// create a test branch and switch to it
		git.branchCreate().setName("test").call();
		RefUpdate rup = db.updateRef(Constants.HEAD);
		rup.link("refs/heads/test");

		// commit something on the test branch
		writeTrashFile("Test.txt", "Some change");
		git.add().addFilepattern("Test.txt").call();
		secondCommit = git.commit().setMessage("Second commit").call();
	}

	@Test
	public void testSimpleCheckout() throws Exception {
		git.checkout().setName("test").call();
	}

	@Test
	public void testCheckout() throws Exception {
		git.checkout().setName("test").call();
		assertEquals("[Test.txt, mode:100644, content:Some change]",
				indexState(CONTENT));
		Ref result = git.checkout().setName("master").call();
		assertEquals("[Test.txt, mode:100644, content:Hello world]",
				indexState(CONTENT));
		assertEquals("refs/heads/master", result.getName());
		assertEquals("refs/heads/master", git.getRepository().getFullBranch());
	}

	@Test
	public void testCheckoutForced() throws Exception {
		writeTrashFile("Test.txt", "Garbage");
		try {
			git.checkout().setName("master").call().getObjectId();
			fail("Expected CheckoutConflictException didn't occur");
		} catch (CheckoutConflictException e) {
			// Expected
		}
		assertEquals(initialCommit.getId(), git.checkout().setName("master")
				.setForced(true).call().getObjectId());
	}

	@Test
	public void testCheckoutForced_deleteFileAndRestore() throws Exception {
		File testFile = new File(db.getWorkTree(), "Test.txt");
		assertTrue(testFile.exists());

		assertEquals("test", git.getRepository().getBranch());
		FileUtils.delete(testFile);
		assertFalse(testFile.exists());
		// Switch from "test" to "master".
		assertEquals(initialCommit.getId(), git.checkout().setName("master")
				.setForced(true).call().getObjectId());
		assertTrue(testFile.exists());

		assertEquals("master", git.getRepository().getBranch());
		FileUtils.delete(testFile);
		assertFalse(testFile.exists());
		// Stay in current branch.
		assertEquals(initialCommit.getId(), git.checkout().setName("master")
				.setForced(true).call().getObjectId());
		assertTrue(testFile.exists());
	}

	@Test
	public void testCheckoutForcedNoChangeNotInIndex() throws Exception {
		git.checkout().setCreateBranch(true).setName("test2").call();
		File f = writeTrashFile("NewFile.txt", "New file");
		git.add().addFilepattern("NewFile.txt").call();
		git.commit().setMessage("New file created").call();
		git.checkout().setName("test").call();
		assertFalse("NewFile.txt should not exist", f.exists());
		writeTrashFile("NewFile.txt", "New file");
		git.add().addFilepattern("NewFile.txt").call();
		git.commit().setMessage("New file created again with same content")
				.call();
		// Now remove the file from the index only. So it exists in both
		// commits, and in the working tree, but not in the index.
		git.rm().addFilepattern("NewFile.txt").setCached(true).call();
		assertTrue("NewFile.txt should exist", f.isFile());
		git.checkout().setForced(true).setName("test2").call();
		assertTrue("NewFile.txt should exist", f.isFile());
		assertEquals(Constants.R_HEADS + "test2", git.getRepository()
				.exactRef(Constants.HEAD).getTarget().getName());
		assertTrue("Force checkout should have undone git rm --cached",
				git.status().call().isClean());
	}

	@Test
	public void testCheckoutNoChangeNotInIndex() throws Exception {
		git.checkout().setCreateBranch(true).setName("test2").call();
		File f = writeTrashFile("NewFile.txt", "New file");
		git.add().addFilepattern("NewFile.txt").call();
		git.commit().setMessage("New file created").call();
		git.checkout().setName("test").call();
		assertFalse("NewFile.txt should not exist", f.exists());
		writeTrashFile("NewFile.txt", "New file");
		git.add().addFilepattern("NewFile.txt").call();
		git.commit().setMessage("New file created again with same content")
				.call();
		// Now remove the file from the index only. So it exists in both
		// commits, and in the working tree, but not in the index.
		git.rm().addFilepattern("NewFile.txt").setCached(true).call();
		assertTrue("NewFile.txt should exist", f.isFile());
		git.checkout().setName("test2").call();
		assertTrue("NewFile.txt should exist", f.isFile());
		assertEquals(Constants.R_HEADS + "test2", git.getRepository()
				.exactRef(Constants.HEAD).getTarget().getName());
		org.eclipse.jgit.api.Status status = git.status().call();
		assertEquals("[NewFile.txt]", status.getRemoved().toString());
		assertEquals("[NewFile.txt]", status.getUntracked().toString());
	}

	@Test
	public void testCreateBranchOnCheckout() throws Exception {
		git.checkout().setCreateBranch(true).setName("test2").call();
		assertNotNull(db.exactRef("refs/heads/test2"));
	}

	@Test
	public void testCheckoutToNonExistingBranch() throws GitAPIException {
		try {
			git.checkout().setName("badbranch").call();
			fail("Should have failed");
		} catch (RefNotFoundException e) {
			// except to hit here
		}
	}

	@Test
	public void testCheckoutWithConflict() throws Exception {
		CheckoutCommand co = git.checkout();
		try {
			writeTrashFile("Test.txt", "Another change");
			assertEquals(Status.NOT_TRIED, co.getResult().getStatus());
			co.setName("master").call();
			fail("Should have failed");
		} catch (Exception e) {
			assertEquals(Status.CONFLICTS, co.getResult().getStatus());
			assertTrue(co.getResult().getConflictList().contains("Test.txt"));
		}
		git.checkout().setName("master").setForced(true).call();
		assertThat(read("Test.txt"), is("Hello world"));
	}

	@Test
	public void testCheckoutWithNonDeletedFiles() throws Exception {
		File testFile = writeTrashFile("temp", "");
		try (FileInputStream fis = new FileInputStream(testFile)) {
			FileUtils.delete(testFile);
			return;
		} catch (IOException e) {
			// the test makes only sense if deletion of
			// a file with open stream fails
		}
		FileUtils.delete(testFile);
		CheckoutCommand co = git.checkout();
		// delete Test.txt in branch test
		testFile = new File(db.getWorkTree(), "Test.txt");
		assertTrue(testFile.exists());
		FileUtils.delete(testFile);
		assertFalse(testFile.exists());
		git.add().addFilepattern("Test.txt");
		git.commit().setMessage("Delete Test.txt").setAll(true).call();
		git.checkout().setName("master").call();
		assertTrue(testFile.exists());
		// lock the file so it can't be deleted (in Windows, that is)
		try (FileInputStream fis = new FileInputStream(testFile)) {
			assertEquals(Status.NOT_TRIED, co.getResult().getStatus());
			co.setName("test").call();
			assertTrue(testFile.exists());
			assertEquals(Status.NONDELETED, co.getResult().getStatus());
			assertTrue(co.getResult().getUndeletedList().contains("Test.txt"));
		}
	}

	@Test
	public void testCheckoutCommit() throws Exception {
		Ref result = git.checkout().setName(initialCommit.name()).call();
		assertEquals("[Test.txt, mode:100644, content:Hello world]",
				indexState(CONTENT));
		assertNull(result);
		assertEquals(initialCommit.name(), git.getRepository().getFullBranch());
	}

	@Test
	public void testCheckoutLightweightTag() throws Exception {
		git.tag().setAnnotated(false).setName("test-tag")
				.setObjectId(initialCommit).call();
		Ref result = git.checkout().setName("test-tag").call();

		assertNull(result);
		assertEquals(initialCommit.getId(), db.resolve(Constants.HEAD));
		assertHeadDetached();
	}

	@Test
	public void testCheckoutAnnotatedTag() throws Exception {
		git.tag().setAnnotated(true).setName("test-tag")
				.setObjectId(initialCommit).call();
		Ref result = git.checkout().setName("test-tag").call();

		assertNull(result);
		assertEquals(initialCommit.getId(), db.resolve(Constants.HEAD));
		assertHeadDetached();
	}

	@Test
	public void testCheckoutRemoteTrackingWithUpstream() throws Exception {
		Repository db2 = createRepositoryWithRemote();
		addRepoToClose(db2);

		Git.wrap(db2).checkout().setCreateBranch(true).setName("test")
				.setStartPoint("origin/test")
				.setUpstreamMode(SetupUpstreamMode.TRACK).call();

		assertEquals("refs/heads/test",
				db2.exactRef(Constants.HEAD).getTarget().getName());
		StoredConfig config = db2.getConfig();
		assertEquals("origin", config.getString(
				ConfigConstants.CONFIG_BRANCH_SECTION, "test",
				ConfigConstants.CONFIG_KEY_REMOTE));
		assertEquals("refs/heads/test", config.getString(
				ConfigConstants.CONFIG_BRANCH_SECTION, "test",
				ConfigConstants.CONFIG_KEY_MERGE));
	}

	@Test
	public void testCheckoutRemoteTrackingWithoutLocalBranch() throws Exception {
		Repository db2 = createRepositoryWithRemote();
		addRepoToClose(db2);

		// checkout remote tracking branch in second repository
		// (no local branches exist yet in second repository)
		Git.wrap(db2).checkout().setName("remotes/origin/test").call();
		assertEquals("[Test.txt, mode:100644, content:Some change]",
				indexState(db2, CONTENT));
	}



	@Test
	public void testCheckoutOfFileWithInexistentParentDir() throws Exception {
		File a = writeTrashFile("dir/a.txt", "A");
		writeTrashFile("dir/b.txt", "A");
		git.add().addFilepattern("dir/a.txt").addFilepattern("dir/b.txt")
				.call();
		git.commit().setMessage("Added dir").call();

		File dir = new File(db.getWorkTree(), "dir");
		FileUtils.delete(dir, FileUtils.RECURSIVE);

		git.checkout().addPath("dir/a.txt").call();
		assertTrue(a.exists());
	}

	@Test
	public void testCheckoutOfDirectoryShouldBeRecursive() throws Exception {
		File a = writeTrashFile("dir/a.txt", "A");
		File b = writeTrashFile("dir/sub/b.txt", "B");
		git.add().addFilepattern("dir").call();
		git.commit().setMessage("Added dir").call();

		write(a, "modified");
		write(b, "modified");
		git.checkout().addPath("dir").call();

		assertThat(read(a), is("A"));
		assertThat(read(b), is("B"));
	}

	@Test
	public void testCheckoutAllPaths() throws Exception {
		File a = writeTrashFile("dir/a.txt", "A");
		File b = writeTrashFile("dir/sub/b.txt", "B");
		git.add().addFilepattern("dir").call();
		git.commit().setMessage("Added dir").call();

		write(a, "modified");
		write(b, "modified");
		git.checkout().setAllPaths(true).call();

		assertThat(read(a), is("A"));
		assertThat(read(b), is("B"));
	}

	@Test
	public void testCheckoutWithStartPoint() throws Exception {
		File a = writeTrashFile("a.txt", "A");
		git.add().addFilepattern("a.txt").call();
		RevCommit first = git.commit().setMessage("Added a").call();

		write(a, "other");
		git.commit().setAll(true).setMessage("Other").call();

		git.checkout().setCreateBranch(true).setName("a")
				.setStartPoint(first.getId().getName()).call();

		assertThat(read(a), is("A"));
	}

	@Test
	public void testCheckoutWithStartPointOnlyCertainFiles() throws Exception {
		File a = writeTrashFile("a.txt", "A");
		File b = writeTrashFile("b.txt", "B");
		git.add().addFilepattern("a.txt").addFilepattern("b.txt").call();
		RevCommit first = git.commit().setMessage("First").call();

		write(a, "other");
		write(b, "other");
		git.commit().setAll(true).setMessage("Other").call();

		git.checkout().setCreateBranch(true).setName("a")
				.setStartPoint(first.getId().getName()).addPath("a.txt").call();

		assertThat(read(a), is("A"));
		assertThat(read(b), is("other"));
	}

	@Test
	public void testDetachedHeadOnCheckout() throws JGitInternalException,
			IOException, GitAPIException {
		CheckoutCommand co = git.checkout();
		co.setName("master").call();

		String commitId = db.exactRef(R_HEADS + MASTER).getObjectId().name();
		co = git.checkout();
		co.setName(commitId).call();

		assertHeadDetached();
	}

	@Test
	public void testUpdateSmudgedEntries() throws Exception {
		git.branchCreate().setName("test2").call();
		RefUpdate rup = db.updateRef(Constants.HEAD);
		rup.link("refs/heads/test2");

		File file = new File(db.getWorkTree(), "Test.txt");
		long size = file.length();
		Instant mTime = TimeUtil.setLastModifiedWithOffset(file.toPath(),
				-5000L);

		DirCache cache = DirCache.lock(db.getIndexFile(), db.getFS());
		DirCacheEntry entry = cache.getEntry("Test.txt");
		assertNotNull(entry);
		entry.setLength(0);
		entry.setLastModified(EPOCH);
		cache.write();
		assertTrue(cache.commit());

		cache = DirCache.read(db.getIndexFile(), db.getFS());
		entry = cache.getEntry("Test.txt");
		assertNotNull(entry);
		assertEquals(0, entry.getLength());
		assertEquals(EPOCH, entry.getLastModifiedInstant());

		Files.setLastModifiedTime(db.getIndexFile().toPath(),
				FileTime.from(FS.DETECTED
						.lastModifiedInstant(db.getIndexFile())
						.minusMillis(5000L)));

		assertNotNull(git.checkout().setName("test").call());

		cache = DirCache.read(db.getIndexFile(), db.getFS());
		entry = cache.getEntry("Test.txt");
		assertNotNull(entry);
		assertEquals(size, entry.getLength());
		assertEquals(mTime, entry.getLastModifiedInstant());
	}

	@Test
	public void testCheckoutOrphanBranch() throws Exception {
		CheckoutCommand co = newOrphanBranchCommand();
		assertCheckoutRef(co.call());

		File HEAD = new File(trash, ".git/HEAD");
		String headRef = read(HEAD);
		assertEquals("ref: refs/heads/orphanbranch\n", headRef);
		assertEquals(2, trash.list().length);

		File heads = new File(trash, ".git/refs/heads");
		assertEquals(2, heads.listFiles().length);

		this.assertNoHead();
		this.assertRepositoryCondition(1);
		assertEquals(CheckoutResult.NOT_TRIED_RESULT, co.getResult());
	}

	private Repository createRepositoryWithRemote() throws IOException,
			URISyntaxException, MalformedURLException, GitAPIException,
			InvalidRemoteException, TransportException {
		// create second repository
		Repository db2 = createWorkRepository();
		try (Git git2 = new Git(db2)) {
			// setup the second repository to fetch from the first repository
			final StoredConfig config = db2.getConfig();
			RemoteConfig remoteConfig = new RemoteConfig(config, "origin");
			URIish uri = new URIish(db.getDirectory().toURI().toURL());
			remoteConfig.addURI(uri);
			remoteConfig.update(config);
			config.save();

			// fetch from first repository
			git2.fetch().setRemote("origin")
					.setRefSpecs("+refs/heads/*:refs/remotes/origin/*").call();
			return db2;
		}
	}

	private CheckoutCommand newOrphanBranchCommand() {
		return git.checkout().setOrphan(true)
				.setName("orphanbranch");
	}

	private static void assertCheckoutRef(Ref ref) {
		assertNotNull(ref);
		assertEquals("refs/heads/orphanbranch", ref.getTarget().getName());
	}

	private void assertNoHead() throws IOException {
		assertNull(db.resolve("HEAD"));
	}

	private void assertHeadDetached() throws IOException {
		Ref head = db.exactRef(Constants.HEAD);
		assertFalse(head.isSymbolic());
		assertSame(head, head.getTarget());
	}

	private void assertRepositoryCondition(int files) throws GitAPIException {
		org.eclipse.jgit.api.Status status = this.git.status().call();
		assertFalse(status.isClean());
		assertEquals(files, status.getAdded().size());
	}

	@Test
	public void testCreateOrphanBranchWithStartCommit() throws Exception {
		CheckoutCommand co = newOrphanBranchCommand();
		Ref ref = co.setStartPoint(initialCommit).call();
		assertCheckoutRef(ref);
		assertEquals(2, trash.list().length);
		this.assertNoHead();
		this.assertRepositoryCondition(1);
	}

	@Test
	public void testCreateOrphanBranchWithStartPoint() throws Exception {
		CheckoutCommand co = newOrphanBranchCommand();
		Ref ref = co.setStartPoint("HEAD^").call();
		assertCheckoutRef(ref);

		assertEquals(2, trash.list().length);
		this.assertNoHead();
		this.assertRepositoryCondition(1);
	}

	@Test
	public void testInvalidRefName() throws Exception {
		try {
			git.checkout().setOrphan(true).setName("../invalidname").call();
			fail("Should have failed");
		} catch (InvalidRefNameException e) {
			// except to hit here
		}
	}

	@Test
	public void testNullRefName() throws Exception {
		try {
			git.checkout().setOrphan(true).setName(null).call();
			fail("Should have failed");
		} catch (InvalidRefNameException e) {
			// except to hit here
		}
	}

	@Test
	public void testAlreadyExists() throws Exception {
		this.git.checkout().setCreateBranch(true).setName("orphanbranch")
				.call();
		this.git.checkout().setName("master").call();

		try {
			newOrphanBranchCommand().call();
			fail("Should have failed");
		} catch (RefAlreadyExistsException e) {
			// except to hit here
		}
	}

	// TODO: write a faster test which depends less on characteristics of
	// underlying filesystem/OS.
	@Test
	public void testCheckoutAutoCrlfTrue() throws Exception {
		int nrOfAutoCrlfTestFiles = 200;

		FileBasedConfig c = db.getConfig();
		c.setString("core", null, "autocrlf", "true");
		c.save();

		AddCommand add = git.add();
		for (int i = 100; i < 100 + nrOfAutoCrlfTestFiles; i++) {
			writeTrashFile("Test_" + i + ".txt", "Hello " + i
					+ " world\nX\nYU\nJK\n");
			add.addFilepattern("Test_" + i + ".txt");
		}
		fsTick(null);
		add.call();
		RevCommit c1 = git.commit().setMessage("add some lines").call();

		add = git.add();
		for (int i = 100; i < 100 + nrOfAutoCrlfTestFiles; i++) {
			writeTrashFile("Test_" + i + ".txt", "Hello " + i
					+ " world\nX\nY\n");
			add.addFilepattern("Test_" + i + ".txt");
		}
		fsTick(null);
		add.call();
		git.commit().setMessage("add more").call();

		git.checkout().setName(c1.getName()).call();

		boolean foundUnsmudged = false;
		DirCache dc = db.readDirCache();
		for (int i = 100; i < 100 + nrOfAutoCrlfTestFiles; i++) {
			DirCacheEntry entry = dc.getEntry(
					"Test_" + i + ".txt");
			if (!entry.isSmudged()) {
				foundUnsmudged = true;
				assertEquals("unexpected file length in git index", 28,
						entry.getLength());
			}
		}
		org.junit.Assume.assumeTrue(foundUnsmudged);
	}

	@Test
	public void testSmudgeFilter_modifyExisting() throws IOException, GitAPIException {
		File script = writeTempFile("sed s/o/e/g");
		StoredConfig config = git.getRepository().getConfig();
		config.setString("filter", "lfs", "smudge",
				"sh " + slashify(script.getPath()));
		config.save();

		writeTrashFile(".gitattributes", "*.txt filter=lfs");
		git.add().addFilepattern(".gitattributes").call();
		git.commit().setMessage("add filter").call();

		writeTrashFile("src/a.tmp", "x");
		// Caution: we need a trailing '\n' since sed on mac always appends
		// linefeeds if missing
		writeTrashFile("src/a.txt", "x\n");
		git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
				.call();
		RevCommit content1 = git.commit().setMessage("add content").call();

		writeTrashFile("src/a.tmp", "foo");
		writeTrashFile("src/a.txt", "foo\n");
		git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
				.call();
		RevCommit content2 = git.commit().setMessage("changed content").call();

		git.checkout().setName(content1.getName()).call();
		git.checkout().setName(content2.getName()).call();

		assertEquals(
				"[.gitattributes, mode:100644, content:*.txt filter=lfs][Test.txt, mode:100644, content:Some change][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]",
				indexState(CONTENT));
		assertEquals(Sets.of("src/a.txt"), git.status().call().getModified());
		assertEquals("foo", read("src/a.tmp"));
		assertEquals("fee\n", read("src/a.txt"));
	}

	@Test
	public void testSmudgeFilter_createNew()
			throws IOException, GitAPIException {
		File script = writeTempFile("sed s/o/e/g");
		StoredConfig config = git.getRepository().getConfig();
		config.setString("filter", "lfs", "smudge",
				"sh " + slashify(script.getPath()));
		config.save();

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

		writeTrashFile(".gitattributes", "*.txt filter=lfs");
		git.add().addFilepattern(".gitattributes").call();
		git.commit().setMessage("add filter").call();

		writeTrashFile("src/a.tmp", "foo");
		// Caution: we need a trailing '\n' since sed on mac always appends
		// linefeeds if missing
		writeTrashFile("src/a.txt", "foo\n");
		git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
				.call();
		RevCommit content = git.commit().setMessage("added content").call();

		git.checkout().setName(initial.getName()).call();
		git.checkout().setName(content.getName()).call();

		assertEquals(
				"[.gitattributes, mode:100644, content:*.txt filter=lfs][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]",
				indexState(CONTENT));
		assertEquals("foo", read("src/a.tmp"));
		assertEquals("fee\n", read("src/a.txt"));
	}

	@Test
	public void testSmudgeFilter_deleteFileAndRestoreFromCommit()
			throws IOException, GitAPIException {
		File script = writeTempFile("sed s/o/e/g");
		StoredConfig config = git.getRepository().getConfig();
		config.setString("filter", "lfs", "smudge",
				"sh " + slashify(script.getPath()));
		config.save();

		writeTrashFile("foo", "foo");
		git.add().addFilepattern("foo").call();
		git.commit().setMessage("initial").call();

		writeTrashFile(".gitattributes", "*.txt filter=lfs");
		git.add().addFilepattern(".gitattributes").call();
		git.commit().setMessage("add filter").call();

		writeTrashFile("src/a.tmp", "foo");
		// Caution: we need a trailing '\n' since sed on mac always appends
		// linefeeds if missing
		writeTrashFile("src/a.txt", "foo\n");
		git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
				.call();
		RevCommit content = git.commit().setMessage("added content").call();

		deleteTrashFile("src/a.txt");
		git.checkout().setStartPoint(content.getName()).addPath("src/a.txt")
				.call();

		assertEquals(
				"[.gitattributes, mode:100644, content:*.txt filter=lfs][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]",
				indexState(CONTENT));
		assertEquals("foo", read("src/a.tmp"));
		assertEquals("fee\n", read("src/a.txt"));
	}

	@Test
	public void testSmudgeFilter_deleteFileAndRestoreFromIndex()
			throws IOException, GitAPIException {
		File script = writeTempFile("sed s/o/e/g");
		StoredConfig config = git.getRepository().getConfig();
		config.setString("filter", "lfs", "smudge",
				"sh " + slashify(script.getPath()));
		config.save();

		writeTrashFile("foo", "foo");
		git.add().addFilepattern("foo").call();
		git.commit().setMessage("initial").call();

		writeTrashFile(".gitattributes", "*.txt filter=lfs");
		git.add().addFilepattern(".gitattributes").call();
		git.commit().setMessage("add filter").call();

		writeTrashFile("src/a.tmp", "foo");
		// Caution: we need a trailing '\n' since sed on mac always appends
		// linefeeds if missing
		writeTrashFile("src/a.txt", "foo\n");
		git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
				.call();
		git.commit().setMessage("added content").call();

		deleteTrashFile("src/a.txt");
		git.checkout().addPath("src/a.txt").call();

		assertEquals(
				"[.gitattributes, mode:100644, content:*.txt filter=lfs][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]",
				indexState(CONTENT));
		assertEquals("foo", read("src/a.tmp"));
		assertEquals("fee\n", read("src/a.txt"));
	}

	@Test
	public void testSmudgeFilter_deleteFileAndCreateBranchAndRestoreFromCommit()
			throws IOException, GitAPIException {
		File script = writeTempFile("sed s/o/e/g");
		StoredConfig config = git.getRepository().getConfig();
		config.setString("filter", "lfs", "smudge",
				"sh " + slashify(script.getPath()));
		config.save();

		writeTrashFile("foo", "foo");
		git.add().addFilepattern("foo").call();
		git.commit().setMessage("initial").call();

		writeTrashFile(".gitattributes", "*.txt filter=lfs");
		git.add().addFilepattern(".gitattributes").call();
		git.commit().setMessage("add filter").call();

		writeTrashFile("src/a.tmp", "foo");
		// Caution: we need a trailing '\n' since sed on mac always appends
		// linefeeds if missing
		writeTrashFile("src/a.txt", "foo\n");
		git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
				.call();
		RevCommit content = git.commit().setMessage("added content").call();

		deleteTrashFile("src/a.txt");
		git.checkout().setName("newBranch").setCreateBranch(true)
				.setStartPoint(content).addPath("src/a.txt").call();

		assertEquals(
				"[.gitattributes, mode:100644, content:*.txt filter=lfs][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]",
				indexState(CONTENT));
		assertEquals("foo", read("src/a.tmp"));
		assertEquals("fee\n", read("src/a.txt"));
	}

	@Test
	public void testSmudgeAndClean() throws Exception {
		File clean_filter = writeTempFile("sed s/V1/@version/g");
		File smudge_filter = writeTempFile("sed s/@version/V1/g");

		try (Git git2 = new Git(db)) {
			StoredConfig config = git.getRepository().getConfig();
			config.setString("filter", "lfs", "smudge",
					"sh " + slashify(smudge_filter.getPath()));
			config.setString("filter", "lfs", "clean",
					"sh " + slashify(clean_filter.getPath()));
			config.setBoolean("filter", "lfs", "useJGitBuiltin", true);
			config.save();
			writeTrashFile(".gitattributes", "filterTest.txt filter=lfs");
			git2.add().addFilepattern(".gitattributes").call();
			git2.commit().setMessage("add attributes").call();

			fsTick(writeTrashFile("filterTest.txt", "hello world, V1\n"));
			git2.add().addFilepattern("filterTest.txt").call();
			RevCommit one = git2.commit().setMessage("add filterText.txt").call();
			assertEquals(
					"[.gitattributes, mode:100644, content:filterTest.txt filter=lfs][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:version https://git-lfs.github.com/spec/v1\noid sha256:7bd5d32e5c494354aa4c2473a1306d0ce7b52cc3bffeb342c03cd517ef8cf8da\nsize 16\n]",
					indexState(CONTENT));

			fsTick(writeTrashFile("filterTest.txt", "bon giorno world, V1\n"));
			git2.add().addFilepattern("filterTest.txt").call();
			RevCommit two = git2.commit().setMessage("modified filterTest.txt").call();

			assertTrue(git2.status().call().isClean());
			assertEquals(
					"[.gitattributes, mode:100644, content:filterTest.txt filter=lfs][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:version https://git-lfs.github.com/spec/v1\noid sha256:087148cccf53b0049c56475c1595113c9da4b638997c3489af8ac7108d51ef13\nsize 21\n]",
					indexState(CONTENT));

			git2.checkout().setName(one.getName()).call();
			assertTrue(git2.status().call().isClean());
			assertEquals(
					"[.gitattributes, mode:100644, content:filterTest.txt filter=lfs][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:version https://git-lfs.github.com/spec/v1\noid sha256:7bd5d32e5c494354aa4c2473a1306d0ce7b52cc3bffeb342c03cd517ef8cf8da\nsize 16\n]",
					indexState(CONTENT));
			assertEquals("hello world, V1\n", read("filterTest.txt"));

			git2.checkout().setName(two.getName()).call();
			assertTrue(git2.status().call().isClean());
			assertEquals(
					"[.gitattributes, mode:100644, content:filterTest.txt filter=lfs][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:version https://git-lfs.github.com/spec/v1\noid sha256:087148cccf53b0049c56475c1595113c9da4b638997c3489af8ac7108d51ef13\nsize 21\n]",
					indexState(CONTENT));
			assertEquals("bon giorno world, V1\n", read("filterTest.txt"));
		}
	}

	@Test
	public void testNonDeletableFilesOnWindows()
			throws GitAPIException, IOException {
		// Only on windows a FileInputStream blocks us from deleting a file
		org.junit.Assume.assumeTrue(SystemReader.getInstance().isWindows());
		writeTrashFile("toBeModified.txt", "a");
		writeTrashFile("toBeDeleted.txt", "a");
		git.add().addFilepattern(".").call();
		RevCommit addFiles = git.commit().setMessage("add more files").call();

		git.rm().setCached(false).addFilepattern("Test.txt")
				.addFilepattern("toBeDeleted.txt").call();
		writeTrashFile("toBeModified.txt", "b");
		writeTrashFile("toBeCreated.txt", "a");
		git.add().addFilepattern(".").call();
		RevCommit crudCommit = git.commit().setMessage("delete, modify, add")
				.call();
		git.checkout().setName(addFiles.getName()).call();
		try ( FileInputStream fis=new FileInputStream(new File(db.getWorkTree(), "Test.txt")) ) {
			CheckoutCommand coCommand = git.checkout();
			coCommand.setName(crudCommit.getName()).call();
			CheckoutResult result = coCommand.getResult();
			assertEquals(Status.NONDELETED, result.getStatus());
			assertEquals("[toBeDeleted.txt]",
					result.getRemovedList().toString());
			assertEquals("[toBeCreated.txt, toBeModified.txt]",
					result.getModifiedList().toString());
			assertEquals("[Test.txt]", result.getUndeletedList().toString());
			assertTrue(result.getConflictList().isEmpty());
		}
	}

	private File writeTempFile(String body) throws IOException {
		File f = File.createTempFile("CheckoutCommandTest_", "");
		JGitTestUtil.write(f, body);
		return f;
	}
}
