aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wolf <thomas.wolf@paranor.ch>2020-04-03 10:39:37 +0200
committerThomas Wolf <thomas.wolf@paranor.ch>2020-04-03 10:40:30 +0200
commit9aaa58052b4f810da7a1b3cd67dadbd50e956934 (patch)
tree5dd23b6ae3200ab396e83b6c51777738a89faae4
parent567bf85479effbfba9adbfb004e65d8c28b6871e (diff)
parent3ae0b5cfeb4ffedb4078d2feb472bb18d589d86e (diff)
downloadjgit-9aaa58052b4f810da7a1b3cd67dadbd50e956934.tar.gz
jgit-9aaa58052b4f810da7a1b3cd67dadbd50e956934.zip
Merge branch 'stable-5.7'
* stable-5.7: FS.runInShell(): handle quoted filters and hooksPath containing blanks Handle non-normalized index also for executable files Prepare 5.7.1-SNAPSHOT builds JGit v5.7.0.202003110725-r Change-Id: I8a8580e44bfa05989d476cf22a029abd4fd407c6 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java42
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java25
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HookTest.java32
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java7
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java17
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java7
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java9
7 files changed, 124 insertions, 15 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 4cc3ca0a53..8084505c10 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
@@ -16,6 +16,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;
@@ -600,41 +601,64 @@ 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)) {
// Commit a file with CR/LF into the index
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 e0d9cbc197..7e0de82d82 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
@@ -12,6 +12,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;
@@ -21,6 +22,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 {
@@ -135,4 +138,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.test/tst/org/eclipse/jgit/util/HookTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HookTest.java
index 254878ae0b..33ed360efd 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HookTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HookTest.java
@@ -259,6 +259,38 @@ public class HookTest extends RepositoryTestCase {
}
@Test
+ public void testHookPathWithBlank() throws Exception {
+ assumeSupportedPlatform();
+
+ File file = writeHookFile("../../a directory/" + PreCommitHook.NAME,
+ "#!/bin/sh\necho \"test $1 $2\"\nread INPUT\necho $INPUT\n"
+ + "echo $GIT_DIR\necho $GIT_WORK_TREE\necho 1>&2 \"stderr\"");
+ StoredConfig cfg = db.getConfig();
+ cfg.load();
+ cfg.setString(ConfigConstants.CONFIG_CORE_SECTION, null,
+ ConfigConstants.CONFIG_KEY_HOOKS_PATH,
+ file.getParentFile().getAbsolutePath());
+ cfg.save();
+ try (ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayOutputStream err = new ByteArrayOutputStream()) {
+ ProcessResult res = FS.DETECTED.runHookIfPresent(db,
+ PreCommitHook.NAME, new String[] { "arg1", "arg2" },
+ new PrintStream(out), new PrintStream(err), "stdin");
+
+ assertEquals("unexpected hook output",
+ "test arg1 arg2\nstdin\n"
+ + db.getDirectory().getAbsolutePath() + '\n'
+ + db.getWorkTree().getAbsolutePath() + '\n',
+ out.toString("UTF-8"));
+ assertEquals("unexpected output on stderr stream", "stderr\n",
+ err.toString("UTF-8"));
+ assertEquals("unexpected exit code", 0, res.getExitCode());
+ assertEquals("unexpected process status", ProcessResult.Status.OK,
+ res.getStatus());
+ }
+ }
+
+ @Test
public void testFailedPreCommitHookBlockCommit() throws Exception {
assumeSupportedPlatform();
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 2d406bd5bd..994af2607c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
@@ -1467,7 +1467,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) {
@@ -1484,7 +1484,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;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
index 216bf2c336..988953b00c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -1747,7 +1747,7 @@ public abstract class FS {
return new ProcessResult(Status.NOT_PRESENT);
}
String cmd = hookFile.getAbsolutePath();
- ProcessBuilder hookProcess = runInShell(cmd, args);
+ ProcessBuilder hookProcess = runInShell(shellQuote(cmd), args);
hookProcess.directory(runDirectory.getAbsoluteFile());
Map<String, String> environment = hookProcess.environment();
environment.put(Constants.GIT_DIR_KEY,
@@ -1770,6 +1770,21 @@ public abstract class FS {
}
}
+ /**
+ * Quote a string (such as a file system path obtained from a Java
+ * {@link File} or {@link Path} object) such that it can be passed as first
+ * argument to {@link #runInShell(String, String[])}.
+ * <p>
+ * This default implementation returns the string unchanged.
+ * </p>
+ *
+ * @param cmd
+ * the String to quote
+ * @return the quoted string
+ */
+ String shellQuote(String cmd) {
+ return cmd;
+ }
/**
* Tries to find a hook matching the given one in the given repository.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
index a0822001ca..c9d2770b18 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
@@ -228,7 +228,7 @@ public class FS_POSIX extends FS {
List<String> argv = new ArrayList<>(4 + args.length);
argv.add("sh"); //$NON-NLS-1$
argv.add("-c"); //$NON-NLS-1$
- argv.add("$0 \"$@\""); //$NON-NLS-1$
+ argv.add(cmd + " \"$@\""); //$NON-NLS-1$
argv.add(cmd);
argv.addAll(Arrays.asList(args));
ProcessBuilder proc = new ProcessBuilder();
@@ -236,6 +236,11 @@ public class FS_POSIX extends FS {
return proc;
}
+ @Override
+ String shellQuote(String cmd) {
+ return QuotedString.BOURNE.quote(cmd);
+ }
+
/** {@inheritDoc} */
@Override
public ProcessResult runHookIfPresent(Repository repository, String hookName,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java
index 82b2818a40..d53bff78ea 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java
@@ -116,14 +116,19 @@ public class FS_Win32_Cygwin extends FS_Win32 {
List<String> argv = new ArrayList<>(4 + args.length);
argv.add("sh.exe"); //$NON-NLS-1$
argv.add("-c"); //$NON-NLS-1$
- argv.add("$0 \"$@\""); //$NON-NLS-1$
- argv.add(cmd.replace(File.separatorChar, '/'));
+ argv.add(cmd + " \"$@\""); //$NON-NLS-1$
+ argv.add(cmd);
argv.addAll(Arrays.asList(args));
ProcessBuilder proc = new ProcessBuilder();
proc.command(argv);
return proc;
}
+ @Override
+ String shellQuote(String cmd) {
+ return QuotedString.BOURNE.quote(cmd.replace(File.separatorChar, '/'));
+ }
+
/** {@inheritDoc} */
@Override
public String relativize(String base, String other) {