From 24f82b533a1774f03fbedb5f32854aa8858fce6d Mon Sep 17 00:00:00 2001 From: Thomas Wolf Date: Wed, 25 Mar 2020 09:13:20 +0100 Subject: [PATCH] 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 --- .../eclipse/jgit/api/CommitCommandTest.java | 42 +++++++++++++++---- .../eclipse/jgit/api/StatusCommandTest.java | 25 +++++++++++ .../jgit/treewalk/WorkingTreeIterator.java | 7 +++- 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java index b5661e8440..b774921178 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java @@ -49,6 +49,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; import java.io.File; import java.util.Date; @@ -633,40 +634,63 @@ public class CommitCommandTest extends RepositoryTestCase { } } - @Test - public void commitWithAutoCrlfAndNonNormalizedIndex() throws Exception { + private void nonNormalizedIndexTest(boolean executable) throws Exception { + String mode = executable ? "100755" : "100644"; try (Git git = new Git(db)) { // Commit a file with CR/LF into the index FileBasedConfig config = db.getConfig(); config.setString("core", null, "autocrlf", "false"); config.save(); - 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.commit().setMessage("Initial").call(); 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)); config.setString("core", null, "autocrlf", "true"); config.save(); 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") .call(); git.commit().setMessage("Second").call(); assertEquals( - "[file.txt, mode:100644, content:line 1\r\nline 1.5\r\nline 2\r\n]" - + "[file2.txt, mode:100644, content:new\nfile\n]", + "[file.txt, mode:" + mode + + ", content:line 1\r\nline 1.5\r\nline 2\r\n]" + + "[file2.txt, mode:" + mode + + ", content:new\nfile\n]", indexState(CONTENT)); writeTrashFile("file2.txt", "new\r\nfile\r\ncontent\r\n"); git.add().addFilepattern("file2.txt").call(); git.commit().setMessage("Third").call(); assertEquals( - "[file.txt, mode:100644, content:line 1\r\nline 1.5\r\nline 2\r\n]" - + "[file2.txt, mode:100644, content:new\nfile\ncontent\n]", + "[file.txt, mode:" + mode + + ", content:line 1\r\nline 1.5\r\nline 2\r\n]" + + "[file2.txt, mode:" + mode + + ", content:new\nfile\ncontent\n]", indexState(CONTENT)); } } + @Test + public void commitWithAutoCrlfAndNonNormalizedIndex() throws Exception { + nonNormalizedIndexTest(false); + } + + @Test + public void commitExecutableWithAutoCrlfAndNonNormalizedIndex() + throws Exception { + assumeTrue(FS.DETECTED.supportsExecute()); + nonNormalizedIndexTest(true); + } + @Test public void testDeletionConflictWithAutoCrlf() throws Exception { try (Git git = new Git(db)) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java index f3ac65ca08..18580ae73d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java @@ -45,6 +45,7 @@ package org.eclipse.jgit.api; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; import java.io.File; import java.io.IOException; @@ -54,6 +55,8 @@ import org.eclipse.jgit.api.errors.NoFilepatternException; import org.eclipse.jgit.errors.NoWorkTreeException; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.Sets; +import org.eclipse.jgit.storage.file.FileBasedConfig; +import org.eclipse.jgit.util.FS; import org.junit.Test; public class StatusCommandTest extends RepositoryTestCase { @@ -168,4 +171,26 @@ public class StatusCommandTest extends RepositoryTestCase { 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()); + } + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java index 7f2d5365a4..35d6e41a9e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java @@ -1500,7 +1500,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { } // Read blob from index and check for CR/LF-delimited text. DirCacheEntry entry = dirCache.getDirCacheEntry(); - if (FileMode.REGULAR_FILE.equals(entry.getFileMode())) { + if ((entry.getRawMode() & FileMode.TYPE_MASK) == FileMode.TYPE_FILE) { ObjectId blobId = entry.getObjectId(); if (entry.getStage() > 0 && entry.getStage() != DirCacheEntry.STAGE_2) { @@ -1517,7 +1517,10 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { break; } if (entry.getStage() == DirCacheEntry.STAGE_2) { - blobId = entry.getObjectId(); + if ((entry.getRawMode() + & FileMode.TYPE_MASK) == FileMode.TYPE_FILE) { + blobId = entry.getObjectId(); + } break; } } -- 2.39.5