Handle non-normalized index also for executable files

Commit 60cf85a4 corrected the handling of check-in for files where
the index version is non-normalized, i.e., contains CR-LF line endings.
However, it did so only for regular files, not executable files.

Bug: 561438
Change-Id: I372cc990c5efeb00315460f36459c0652d5d1e77
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
This commit is contained in:
Thomas Wolf 2020-03-25 09:13:20 +01:00
parent 2415571370
commit 24f82b533a
3 changed files with 63 additions and 11 deletions

View File

@ -49,6 +49,7 @@
import static org.junit.Assert.assertSame; import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
import java.io.File; import java.io.File;
import java.util.Date; import java.util.Date;
@ -633,40 +634,63 @@ public void commitOnlyShouldHandleIgnored() throws Exception {
} }
} }
@Test private void nonNormalizedIndexTest(boolean executable) throws Exception {
public void commitWithAutoCrlfAndNonNormalizedIndex() throws Exception { String mode = executable ? "100755" : "100644";
try (Git git = new Git(db)) { try (Git git = new Git(db)) {
// Commit a file with CR/LF into the index // Commit a file with CR/LF into the index
FileBasedConfig config = db.getConfig(); FileBasedConfig config = db.getConfig();
config.setString("core", null, "autocrlf", "false"); config.setString("core", null, "autocrlf", "false");
config.save(); config.save();
writeTrashFile("file.txt", "line 1\r\nline 2\r\n"); File testFile = writeTrashFile("file.txt", "line 1\r\nline 2\r\n");
if (executable) {
FS.DETECTED.setExecute(testFile, true);
}
git.add().addFilepattern("file.txt").call(); git.add().addFilepattern("file.txt").call();
git.commit().setMessage("Initial").call(); git.commit().setMessage("Initial").call();
assertEquals( assertEquals(
"[file.txt, mode:100644, content:line 1\r\nline 2\r\n]", "[file.txt, mode:" + mode
+ ", content:line 1\r\nline 2\r\n]",
indexState(CONTENT)); indexState(CONTENT));
config.setString("core", null, "autocrlf", "true"); config.setString("core", null, "autocrlf", "true");
config.save(); config.save();
writeTrashFile("file.txt", "line 1\r\nline 1.5\r\nline 2\r\n"); writeTrashFile("file.txt", "line 1\r\nline 1.5\r\nline 2\r\n");
writeTrashFile("file2.txt", "new\r\nfile\r\n"); testFile = writeTrashFile("file2.txt", "new\r\nfile\r\n");
if (executable) {
FS.DETECTED.setExecute(testFile, true);
}
git.add().addFilepattern("file.txt").addFilepattern("file2.txt") git.add().addFilepattern("file.txt").addFilepattern("file2.txt")
.call(); .call();
git.commit().setMessage("Second").call(); git.commit().setMessage("Second").call();
assertEquals( assertEquals(
"[file.txt, mode:100644, content:line 1\r\nline 1.5\r\nline 2\r\n]" "[file.txt, mode:" + mode
+ "[file2.txt, mode:100644, content:new\nfile\n]", + ", content:line 1\r\nline 1.5\r\nline 2\r\n]"
+ "[file2.txt, mode:" + mode
+ ", content:new\nfile\n]",
indexState(CONTENT)); indexState(CONTENT));
writeTrashFile("file2.txt", "new\r\nfile\r\ncontent\r\n"); writeTrashFile("file2.txt", "new\r\nfile\r\ncontent\r\n");
git.add().addFilepattern("file2.txt").call(); git.add().addFilepattern("file2.txt").call();
git.commit().setMessage("Third").call(); git.commit().setMessage("Third").call();
assertEquals( assertEquals(
"[file.txt, mode:100644, content:line 1\r\nline 1.5\r\nline 2\r\n]" "[file.txt, mode:" + mode
+ "[file2.txt, mode:100644, content:new\nfile\ncontent\n]", + ", content:line 1\r\nline 1.5\r\nline 2\r\n]"
+ "[file2.txt, mode:" + mode
+ ", content:new\nfile\ncontent\n]",
indexState(CONTENT)); indexState(CONTENT));
} }
} }
@Test
public void commitWithAutoCrlfAndNonNormalizedIndex() throws Exception {
nonNormalizedIndexTest(false);
}
@Test
public void commitExecutableWithAutoCrlfAndNonNormalizedIndex()
throws Exception {
assumeTrue(FS.DETECTED.supportsExecute());
nonNormalizedIndexTest(true);
}
@Test @Test
public void testDeletionConflictWithAutoCrlf() throws Exception { public void testDeletionConflictWithAutoCrlf() throws Exception {
try (Git git = new Git(db)) { try (Git git = new Git(db)) {

View File

@ -45,6 +45,7 @@
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -54,6 +55,8 @@
import org.eclipse.jgit.errors.NoWorkTreeException; import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.Sets; import org.eclipse.jgit.lib.Sets;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
import org.junit.Test; import org.junit.Test;
public class StatusCommandTest extends RepositoryTestCase { public class StatusCommandTest extends RepositoryTestCase {
@ -168,4 +171,26 @@ public void testDifferentStatesWithPaths() throws IOException,
assertEquals(Sets.of("a", "D/b", "D/D/d"), stat.getModified()); assertEquals(Sets.of("a", "D/b", "D/D/d"), stat.getModified());
} }
} }
@Test
public void testExecutableWithNonNormalizedIndex() throws Exception {
assumeTrue(FS.DETECTED.supportsExecute());
try (Git git = new Git(db)) {
// Commit a file with CR/LF into the index
FileBasedConfig config = db.getConfig();
config.setString("core", null, "autocrlf", "false");
config.save();
File testFile = writeTrashFile("file.txt", "line 1\r\nline 2\r\n");
FS.DETECTED.setExecute(testFile, true);
git.add().addFilepattern("file.txt").call();
git.commit().setMessage("Initial").call();
assertEquals(
"[file.txt, mode:100755, content:line 1\r\nline 2\r\n]",
indexState(CONTENT));
config.setString("core", null, "autocrlf", "true");
config.save();
Status status = git.status().call();
assertTrue("Expected no differences", status.isClean());
}
}
} }

View File

@ -1500,7 +1500,7 @@ private boolean hasCrLfInIndex(DirCacheIterator dirCache) {
} }
// Read blob from index and check for CR/LF-delimited text. // Read blob from index and check for CR/LF-delimited text.
DirCacheEntry entry = dirCache.getDirCacheEntry(); DirCacheEntry entry = dirCache.getDirCacheEntry();
if (FileMode.REGULAR_FILE.equals(entry.getFileMode())) { if ((entry.getRawMode() & FileMode.TYPE_MASK) == FileMode.TYPE_FILE) {
ObjectId blobId = entry.getObjectId(); ObjectId blobId = entry.getObjectId();
if (entry.getStage() > 0 if (entry.getStage() > 0
&& entry.getStage() != DirCacheEntry.STAGE_2) { && entry.getStage() != DirCacheEntry.STAGE_2) {
@ -1517,7 +1517,10 @@ private boolean hasCrLfInIndex(DirCacheIterator dirCache) {
break; break;
} }
if (entry.getStage() == DirCacheEntry.STAGE_2) { if (entry.getStage() == DirCacheEntry.STAGE_2) {
blobId = entry.getObjectId(); if ((entry.getRawMode()
& FileMode.TYPE_MASK) == FileMode.TYPE_FILE) {
blobId = entry.getObjectId();
}
break; break;
} }
} }