/* * Copyright (C) 2020 Thomas Wolf 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.attributes; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.BufferedInputStream; import java.io.File; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.Arrays; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.ResetCommand.ResetType; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheEntry; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.storage.file.FileBasedConfig; import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.RawParseUtils; import org.junit.Test; /** * End-to-end tests for some attribute combinations. Writes files, commit them, * examines the index, deletes the files, performs a hard reset and checks file * contents again. */ public class AttributeFileTests extends RepositoryTestCase { @Test public void testTextAutoCoreEolCoreAutoCrLfInput() throws Exception { FileBasedConfig cfg = db.getConfig(); cfg.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null, ConfigConstants.CONFIG_KEY_AUTOCRLF, false); cfg.save(); final String content = "Line1\nLine2\n"; try (Git git = Git.wrap(db)) { writeTrashFile(".gitattributes", "* text=auto"); File dummy = writeTrashFile("dummy.txt", content); git.add().addFilepattern(".").call(); git.commit().setMessage("Commit with LF").call(); assertEquals("Unexpected index state", "[.gitattributes, mode:100644, content:* text=auto]" + "[dummy.txt, mode:100644, content:" + content + ']', indexState(CONTENT)); assertTrue("Should be able to delete " + dummy, dummy.delete()); cfg.setString(ConfigConstants.CONFIG_CORE_SECTION, null, ConfigConstants.CONFIG_KEY_EOL, "crlf"); cfg.setString(ConfigConstants.CONFIG_CORE_SECTION, null, ConfigConstants.CONFIG_KEY_AUTOCRLF, "input"); cfg.save(); git.reset().setMode(ResetType.HARD).call(); assertTrue("File " + dummy + "should exist", dummy.isFile()); String textFile = RawParseUtils.decode(IO.readFully(dummy, 512)); assertEquals("Unexpected text content", content, textFile); } } @Test public void testTextAutoEolLf() throws Exception { writeTrashFile(".gitattributes", "* text=auto eol=lf"); performTest("Test\r\nFile", "Test\nFile", "Test\nFile"); } @Test public void testTextAutoEolCrLf() throws Exception { writeTrashFile(".gitattributes", "* text=auto eol=crlf"); performTest("Test\r\nFile", "Test\nFile", "Test\r\nFile"); } private void performTest(String initial, String index, String finalText) throws Exception { File dummy = writeTrashFile("dummy.foo", initial); byte[] data = readTestResource("add.png"); assertTrue("Expected some binary data", data.length > 100); File binary = writeTrashFile("add.png", ""); Files.write(binary.toPath(), data); try (Git git = Git.wrap(db)) { git.add().addFilepattern(".").call(); git.commit().setMessage("test commit").call(); // binary should be unchanged, dummy should match "index" verifyIndexContent("dummy.foo", index.getBytes(StandardCharsets.UTF_8)); verifyIndexContent("add.png", data); assertTrue("Should be able to delete " + dummy, dummy.delete()); assertTrue("Should be able to delete " + binary, binary.delete()); git.reset().setMode(ResetType.HARD).call(); assertTrue("File " + dummy + " should exist", dummy.isFile()); assertTrue("File " + binary + " should exist", binary.isFile()); // binary should be unchanged, dummy should match "finalText" String textFile = RawParseUtils.decode(IO.readFully(dummy, 512)); assertEquals("Unexpected text content", finalText, textFile); byte[] binaryFile = IO.readFully(binary, 512); assertArrayEquals("Unexpected binary content", data, binaryFile); } } private byte[] readTestResource(String name) throws Exception { try (InputStream in = new BufferedInputStream( getClass().getResourceAsStream(name))) { byte[] data = new byte[512]; int read = in.read(data); if (read == data.length) { return data; } return Arrays.copyOf(data, read); } } private void verifyIndexContent(String path, byte[] expectedContent) throws Exception { DirCache dc = db.readDirCache(); for (int i = 0; i < dc.getEntryCount(); ++i) { DirCacheEntry entry = dc.getEntry(i); if (path.equals(entry.getPathString())) { byte[] data = db.open(entry.getObjectId(), Constants.OBJ_BLOB) .getCachedBytes(); assertArrayEquals("Unexpected index content for " + path, expectedContent, data); return; } } fail("Path not found in index: " + path); } }