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>
This commit is contained in:
commit
9aaa58052b
|
@ -16,6 +16,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;
|
||||||
|
@ -600,40 +601,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)) {
|
||||||
|
|
|
@ -12,6 +12,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;
|
||||||
|
@ -21,6 +22,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 {
|
||||||
|
@ -135,4 +138,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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -258,6 +258,38 @@ public void testRunHookHooksPathAbsolute() throws Exception {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@Test
|
||||||
public void testFailedPreCommitHookBlockCommit() throws Exception {
|
public void testFailedPreCommitHookBlockCommit() throws Exception {
|
||||||
assumeSupportedPlatform();
|
assumeSupportedPlatform();
|
||||||
|
|
|
@ -1467,7 +1467,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) {
|
||||||
|
@ -1484,7 +1484,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1747,7 +1747,7 @@ protected ProcessResult internalRunHookIfPresent(Repository repository,
|
||||||
return new ProcessResult(Status.NOT_PRESENT);
|
return new ProcessResult(Status.NOT_PRESENT);
|
||||||
}
|
}
|
||||||
String cmd = hookFile.getAbsolutePath();
|
String cmd = hookFile.getAbsolutePath();
|
||||||
ProcessBuilder hookProcess = runInShell(cmd, args);
|
ProcessBuilder hookProcess = runInShell(shellQuote(cmd), args);
|
||||||
hookProcess.directory(runDirectory.getAbsoluteFile());
|
hookProcess.directory(runDirectory.getAbsoluteFile());
|
||||||
Map<String, String> environment = hookProcess.environment();
|
Map<String, String> environment = hookProcess.environment();
|
||||||
environment.put(Constants.GIT_DIR_KEY,
|
environment.put(Constants.GIT_DIR_KEY,
|
||||||
|
@ -1770,6 +1770,21 @@ protected ProcessResult internalRunHookIfPresent(Repository repository,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* Tries to find a hook matching the given one in the given repository.
|
||||||
|
|
|
@ -228,7 +228,7 @@ public ProcessBuilder runInShell(String cmd, String[] args) {
|
||||||
List<String> argv = new ArrayList<>(4 + args.length);
|
List<String> argv = new ArrayList<>(4 + args.length);
|
||||||
argv.add("sh"); //$NON-NLS-1$
|
argv.add("sh"); //$NON-NLS-1$
|
||||||
argv.add("-c"); //$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.add(cmd);
|
||||||
argv.addAll(Arrays.asList(args));
|
argv.addAll(Arrays.asList(args));
|
||||||
ProcessBuilder proc = new ProcessBuilder();
|
ProcessBuilder proc = new ProcessBuilder();
|
||||||
|
@ -236,6 +236,11 @@ public ProcessBuilder runInShell(String cmd, String[] args) {
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String shellQuote(String cmd) {
|
||||||
|
return QuotedString.BOURNE.quote(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public ProcessResult runHookIfPresent(Repository repository, String hookName,
|
public ProcessResult runHookIfPresent(Repository repository, String hookName,
|
||||||
|
|
|
@ -116,14 +116,19 @@ public ProcessBuilder runInShell(String cmd, String[] args) {
|
||||||
List<String> argv = new ArrayList<>(4 + args.length);
|
List<String> argv = new ArrayList<>(4 + args.length);
|
||||||
argv.add("sh.exe"); //$NON-NLS-1$
|
argv.add("sh.exe"); //$NON-NLS-1$
|
||||||
argv.add("-c"); //$NON-NLS-1$
|
argv.add("-c"); //$NON-NLS-1$
|
||||||
argv.add("$0 \"$@\""); //$NON-NLS-1$
|
argv.add(cmd + " \"$@\""); //$NON-NLS-1$
|
||||||
argv.add(cmd.replace(File.separatorChar, '/'));
|
argv.add(cmd);
|
||||||
argv.addAll(Arrays.asList(args));
|
argv.addAll(Arrays.asList(args));
|
||||||
ProcessBuilder proc = new ProcessBuilder();
|
ProcessBuilder proc = new ProcessBuilder();
|
||||||
proc.command(argv);
|
proc.command(argv);
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String shellQuote(String cmd) {
|
||||||
|
return QuotedString.BOURNE.quote(cmd.replace(File.separatorChar, '/'));
|
||||||
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public String relativize(String base, String other) {
|
public String relativize(String base, String other) {
|
||||||
|
|
Loading…
Reference in New Issue