Merge "ReceivePack: Use error message if set"
diff --git a/Documentation/config-options.md b/Documentation/config-options.md
new file mode 100644
index 0000000..94ef5b9
--- /dev/null
+++ b/Documentation/config-options.md
@@ -0,0 +1,57 @@
+# JGit configuration options
+
+## Legend
+
+| git option | description |
+|------------|-------------|
+| ✅ | option defined by native git |
+| ⃞ | jgit custom option not supported by native git |
+
+## __core__ options
+
+| option | default | git option | description |
+|---------|---------|------------|-------------|
+| `core.bigFileThreshold` | `52428800` (50 MiB) | ✅ | Maximum file size that will be delta compressed. Files larger than this size are stored deflated, without attempting delta compression. |
+| `core.compression` | `-1` (default compression) | ✅ | An integer -1..9, indicating a default compression level. -1 is the zlib default. 0 means no compression, and 1..9 are various speed/size tradeoffs, 9 being slowest.|
+
+## __gc__ options
+
+| option | default | git option | description |
+|---------|---------|------------|-------------|
+| `gc.aggressiveDepth` | 50 | ✅ | The depth parameter used in the delta compression algorithm used by aggressive garbage collection. |
+| `gc.aggressiveWindow` | 250 | ✅ | The window size parameter used in the delta compression algorithm used by aggressive garbage collection. |
+| `gc.auto` | `6700` | ✅ | Number of loose objects until auto gc combines all loose objects into a pack and consolidates all existing packs into one. Setting to 0 disables automatic packing of loose objects. |
+| `gc.autoDetach` | `true` | ✅ | Make auto gc return immediately and run in background. |
+| `gc.autoPackLimit` | `50` | ✅ | Number of packs until auto gc consolidates existing packs (except those marked with a .keep file) into a single pack. Setting `gc.autoPackLimit` to 0 disables automatic consolidation of packs. |
+| `gc.logExpiry` | `1.day.ago` | ✅ | If the file `gc.log` exists, then auto gc will print its content and exit successfully instead of running unless that file is more than `gc.logExpiry` old. |
+| `gc.pruneExpire` | `2.weeks.ago` | ✅ | Grace period after which unreachable objects will be pruned. |
+| `gc.prunePackExpire` | `1.hour.ago` | ⃞ | Grace period after which packfiles only containing unreachable objects will be pruned. |
+
+## __pack__ options
+
+| option | default | git option | description |
+|---------|---------|------------|-------------|
+| `pack.bitmapContiguousCommitCount` | `100` | ⃞ | Count of most recent commits for which to build bitmaps. |
+| `pack.bitmapDistantCommitSpan` | `5000` | ⃞ | Span of commits when building bitmaps for distant history. |
+| `pack.bitmapExcessiveBranchCount` | `100` | ⃞ | The count of branches deemed "excessive". If the count of branches in a repository exceeds this number and bitmaps are enabled, "inactive" branches will have fewer bitmaps than "active" branches. |
+| `pack.bitmapInactiveBranchAgeInDays` | `90` | ⃞ | Age in days that marks a branch as "inactive" for bitmap creation. |
+| `pack.bitmapRecentCommitCount` | `20000` | ⃞ | Count at which to switch from `bitmapRecentCommitSpan` to `bitmapDistantCommitSpan`. |
+| `pack.bitmapRecentCommitSpan` | `100` | ⃞ | Span of commits when building bitmaps for recent history. |
+| `pack.buildBitmaps` | `true` | ⃞ synonym for `repack.writeBitmaps` | Whether index writer is allowed to build bitmaps for indexes. |
+| `pack.compression` | `core.compression` | ✅ | Compression level applied to objects in the pack. |
+| `pack.cutDeltaChains` | `false` | ⃞ | Whether existing delta chains should be cut at {@link #getMaxDeltaDepth() |
+| `pack.deltaCacheLimit` | `100` | ✅ | Maximum size in bytes of a delta to cache. |
+| `pack.deltaCacheSize` | `52428800` (50 MiB) | ✅ | Size of the in-memory delta cache. |
+| `pack.deltaCompression` | `true` | ⃞ | Whether the writer will create new deltas on the fly. `true` if the pack writer will create a new delta when either `pack.reuseDeltas` is false, or no suitable delta is available for reuse. |
+| `pack.depth` | `50` | ✅ | Maximum depth of delta chain set up for the pack writer. |
+| `pack.indexVersion` | `2` | ✅ | Pack index file format version. |
+| `pack.minSizePreventRacyPack` | `104857600` (100 MiB) | ⃞ | Minimum packfile size for which we wait before opening a newly written pack to prevent its lastModified timestamp could be racy if `pack.waitPreventRacyPack` is `true`. |
+| `pack.preserveOldPacks` | `false` | ⃞ | Whether to preserve old packs in a preserved directory. |
+| `prunePreserved`, only via API of PackConfig | `false` | ⃞ | Whether to remove preserved pack files in a preserved directory. |
+| `pack.reuseDeltas` | `true` |⃞ | Whether to reuse deltas existing in repository. |
+| `pack.reuseObjects` | `true` | ⃞ | Whether to reuse existing objects representation in repository. |
+| `pack.singlePack` | `false` | ⃞ | Whether all of `refs/*` should be packed in a single pack. |
+| `pack.threads` | `0` (auto-detect number of processors) | ✅ | Number of threads to use for delta compression. |
+| `pack.waitPreventRacyPack` | `false` | ⃞ | Whether we wait before opening a newly written pack to prevent its lastModified timestamp could be racy. |
+| `pack.window` | `10` | ✅ | Number of objects to try when looking for a delta base per thread searching for deltas. |
+| `pack.windowMemory` | `0` (unlimited) | ✅ | Maximum number of bytes to put into the delta search window. |
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 4cc3ca0..8084505 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.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 @@
}
}
- @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 e0d9cbc..7e0de82 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 @@
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.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 @@
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/FileUtilsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java
index f9ec5d8..2b1fb2e 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java
@@ -79,6 +79,15 @@
}
@Test
+ public void testDeleteReadOnlyFile() throws IOException {
+ File f = new File(trash, "f");
+ FileUtils.createNewFile(f);
+ assertTrue(f.setReadOnly());
+ FileUtils.delete(f);
+ assertFalse(f.exists());
+ }
+
+ @Test
public void testDeleteRecursive() throws IOException {
File f1 = new File(trash, "test/test/a");
FileUtils.mkdirs(f1.getParentFile());
@@ -339,6 +348,34 @@
}
@Test
+ public void testDeleteNonRecursiveTreeNotOk() throws IOException {
+ File t = new File(trash, "t");
+ FileUtils.mkdir(t);
+ File f = new File(t, "f");
+ FileUtils.createNewFile(f);
+ try {
+ FileUtils.delete(t, FileUtils.EMPTY_DIRECTORIES_ONLY);
+ fail("expected failure to delete f");
+ } catch (IOException e) {
+ assertTrue(e.getMessage().endsWith(t.getAbsolutePath()));
+ }
+ assertTrue(f.exists());
+ assertTrue(t.exists());
+ }
+
+ @Test
+ public void testDeleteNonRecursiveTreeIgnoreError() throws IOException {
+ File t = new File(trash, "t");
+ FileUtils.mkdir(t);
+ File f = new File(t, "f");
+ FileUtils.createNewFile(f);
+ FileUtils.delete(t,
+ FileUtils.EMPTY_DIRECTORIES_ONLY | FileUtils.IGNORE_ERRORS);
+ assertTrue(f.exists());
+ assertTrue(t.exists());
+ }
+
+ @Test
public void testRenameOverNonExistingFile() throws IOException {
File d = new File(trash, "d");
FileUtils.mkdirs(d);
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 254878a..33ed360 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 @@
}
@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/lib/ConfigConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
index e607edc..eef822f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -542,4 +542,124 @@
* @since 5.1.13
*/
public static final String CONFIG_JMX_SECTION = "jmx";
+
+ /**
+ * The "pack.bigfilethreshold" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_BIGFILE_THRESHOLD = "bigfilethreshold";
+
+ /**
+ * The "pack.bitmapContiguousCommitCount" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_BITMAP_CONTIGUOUS_COMMIT_COUNT = "bitmapcontiguouscommitcount";
+
+ /**
+ * The "pack.bitmapDistantCommitSpan" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_BITMAP_DISTANT_COMMIT_SPAN = "bitmapdistantcommitspan";
+
+ /**
+ * The "pack.bitmapExcessiveBranchCount" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_BITMAP_EXCESSIVE_BRANCH_COUNT = "bitmapexcessivebranchcount";
+
+ /**
+ * The "pack.bitmapInactiveBranchAgeInDays" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_BITMAP_INACTIVE_BRANCH_AGE_INDAYS = "bitmapinactivebranchageindays";
+
+ /**
+ * The "pack.bitmapRecentCommitSpan" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_BITMAP_RECENT_COMMIT_COUNT = "bitmaprecentcommitspan";
+
+ /**
+ * The "pack.buildBitmaps" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_BUILD_BITMAPS = "buildbitmaps";
+
+ /**
+ * The "pack.cutDeltaChains" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_CUT_DELTACHAINS = "cutdeltachains";
+
+ /**
+ * The "pack.deltaCacheLimit" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_DELTA_CACHE_LIMIT = "deltacachelimit";
+
+ /**
+ * The "pack.deltaCacheSize" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_DELTA_CACHE_SIZE = "deltacachesize";
+
+ /**
+ * The "pack.deltaCompression" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_DELTA_COMPRESSION = "deltacompression";
+
+ /**
+ * The "pack.depth" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_DEPTH = "depth";
+
+ /**
+ * The "pack.minSizePreventRacyPack" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_MIN_SIZE_PREVENT_RACYPACK = "minsizepreventracypack";
+
+ /**
+ * The "pack.reuseDeltas" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_REUSE_DELTAS = "reusedeltas";
+
+ /**
+ * The "pack.reuseObjects" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_REUSE_OBJECTS = "reuseobjects";
+
+ /**
+ * The "pack.singlePack" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_SINGLE_PACK = "singlepack";
+
+ /**
+ * The "pack.threads" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_THREADS = "threads";
+
+ /**
+ * The "pack.waitPreventRacyPack" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_WAIT_PREVENT_RACYPACK = "waitpreventracypack";
+
+ /**
+ * The "pack.window" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_WINDOW = "window";
+
+ /**
+ * The "pack.windowMemory" key
+ * @since 5.8
+ */
+ public static final String CONFIG_KEY_WINDOW_MEMORY = "windowmemory";
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileRepositoryBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileRepositoryBuilder.java
index 553d875..d476a0d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileRepositoryBuilder.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileRepositoryBuilder.java
@@ -32,7 +32,7 @@
* <pre>
* new FileRepositoryBuilder() //
* .setGitDir(gitDirArgument) // --git-dir if supplied, no-op if null
- * .readEnviroment() // scan environment GIT_* variables
+ * .readEnvironment() // scan environment GIT_* variables
* .findGitDir() // scan up the file system tree
* .build()
* </pre>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java
index 259f011..f76dd27 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java
@@ -11,6 +11,31 @@
package org.eclipse.jgit.storage.pack;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_CORE_SECTION;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BIGFILE_THRESHOLD;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_CONTIGUOUS_COMMIT_COUNT;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_DISTANT_COMMIT_SPAN;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_EXCESSIVE_BRANCH_COUNT;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_INACTIVE_BRANCH_AGE_INDAYS;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_RECENT_COMMIT_COUNT;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BUILD_BITMAPS;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_COMPRESSION;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_CUT_DELTACHAINS;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DELTA_CACHE_LIMIT;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DELTA_CACHE_SIZE;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DELTA_COMPRESSION;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DEPTH;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_INDEXVERSION;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_MIN_SIZE_PREVENT_RACYPACK;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_REUSE_DELTAS;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_REUSE_OBJECTS;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_SINGLE_PACK;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_THREADS;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_WAIT_PREVENT_RACYPACK;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_WINDOW;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_WINDOW_MEMORY;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_PACK_SECTION;
+
import java.util.concurrent.Executor;
import java.util.zip.Deflater;
@@ -1101,52 +1126,63 @@
* configuration to read properties from.
*/
public void fromConfig(Config rc) {
- setMaxDeltaDepth(rc.getInt("pack", "depth", getMaxDeltaDepth())); //$NON-NLS-1$ //$NON-NLS-2$
- setDeltaSearchWindowSize(rc.getInt(
- "pack", "window", getDeltaSearchWindowSize())); //$NON-NLS-1$ //$NON-NLS-2$
- setDeltaSearchMemoryLimit(rc.getLong(
- "pack", "windowmemory", getDeltaSearchMemoryLimit())); //$NON-NLS-1$ //$NON-NLS-2$
- setDeltaCacheSize(rc.getLong(
- "pack", "deltacachesize", getDeltaCacheSize())); //$NON-NLS-1$ //$NON-NLS-2$
- setDeltaCacheLimit(rc.getInt(
- "pack", "deltacachelimit", getDeltaCacheLimit())); //$NON-NLS-1$ //$NON-NLS-2$
- setCompressionLevel(rc.getInt("pack", "compression", //$NON-NLS-1$ //$NON-NLS-2$
- rc.getInt("core", "compression", getCompressionLevel()))); //$NON-NLS-1$ //$NON-NLS-2$
- setIndexVersion(rc.getInt("pack", "indexversion", getIndexVersion())); //$NON-NLS-1$ //$NON-NLS-2$
- setBigFileThreshold(rc.getInt(
- "core", "bigfilethreshold", getBigFileThreshold())); //$NON-NLS-1$ //$NON-NLS-2$
- setThreads(rc.getInt("pack", "threads", getThreads())); //$NON-NLS-1$ //$NON-NLS-2$
+ setMaxDeltaDepth(rc.getInt(CONFIG_PACK_SECTION, CONFIG_KEY_DEPTH,
+ getMaxDeltaDepth()));
+ setDeltaSearchWindowSize(rc.getInt(CONFIG_PACK_SECTION,
+ CONFIG_KEY_WINDOW, getDeltaSearchWindowSize()));
+ setDeltaSearchMemoryLimit(rc.getLong(CONFIG_PACK_SECTION,
+ CONFIG_KEY_WINDOW_MEMORY, getDeltaSearchMemoryLimit()));
+ setDeltaCacheSize(rc.getLong(CONFIG_PACK_SECTION,
+ CONFIG_KEY_DELTA_CACHE_SIZE, getDeltaCacheSize()));
+ setDeltaCacheLimit(rc.getInt(CONFIG_PACK_SECTION,
+ CONFIG_KEY_DELTA_CACHE_LIMIT, getDeltaCacheLimit()));
+ setCompressionLevel(rc.getInt(CONFIG_PACK_SECTION,
+ CONFIG_KEY_COMPRESSION, rc.getInt(CONFIG_CORE_SECTION,
+ CONFIG_KEY_COMPRESSION, getCompressionLevel())));
+ setIndexVersion(rc.getInt(CONFIG_PACK_SECTION,
+ CONFIG_KEY_INDEXVERSION,
+ getIndexVersion()));
+ setBigFileThreshold(rc.getInt(CONFIG_CORE_SECTION,
+ CONFIG_KEY_BIGFILE_THRESHOLD, getBigFileThreshold()));
+ setThreads(rc.getInt(CONFIG_PACK_SECTION, CONFIG_KEY_THREADS,
+ getThreads()));
// These variables aren't standardized
- //
- setReuseDeltas(rc.getBoolean("pack", "reusedeltas", isReuseDeltas())); //$NON-NLS-1$ //$NON-NLS-2$
- setReuseObjects(
- rc.getBoolean("pack", "reuseobjects", isReuseObjects())); //$NON-NLS-1$ //$NON-NLS-2$
- setDeltaCompress(
- rc.getBoolean("pack", "deltacompression", isDeltaCompress())); //$NON-NLS-1$ //$NON-NLS-2$
- setCutDeltaChains(
- rc.getBoolean("pack", "cutdeltachains", getCutDeltaChains())); //$NON-NLS-1$ //$NON-NLS-2$
- setSinglePack(
- rc.getBoolean("pack", "singlepack", getSinglePack())); //$NON-NLS-1$ //$NON-NLS-2$
- setBuildBitmaps(
- rc.getBoolean("pack", "buildbitmaps", isBuildBitmaps())); //$NON-NLS-1$ //$NON-NLS-2$
- setBitmapContiguousCommitCount(
- rc.getInt("pack", "bitmapcontiguouscommitcount", //$NON-NLS-1$ //$NON-NLS-2$
- getBitmapContiguousCommitCount()));
- setBitmapRecentCommitCount(rc.getInt("pack", "bitmaprecentcommitcount", //$NON-NLS-1$ //$NON-NLS-2$
+ setReuseDeltas(rc.getBoolean(CONFIG_PACK_SECTION,
+ CONFIG_KEY_REUSE_DELTAS, isReuseDeltas()));
+ setReuseObjects(rc.getBoolean(CONFIG_PACK_SECTION,
+ CONFIG_KEY_REUSE_OBJECTS, isReuseObjects()));
+ setDeltaCompress(rc.getBoolean(CONFIG_PACK_SECTION,
+ CONFIG_KEY_DELTA_COMPRESSION, isDeltaCompress()));
+ setCutDeltaChains(rc.getBoolean(CONFIG_PACK_SECTION,
+ CONFIG_KEY_CUT_DELTACHAINS, getCutDeltaChains()));
+ setSinglePack(rc.getBoolean(CONFIG_PACK_SECTION,
+ CONFIG_KEY_SINGLE_PACK,
+ getSinglePack()));
+ setBuildBitmaps(rc.getBoolean(CONFIG_PACK_SECTION,
+ CONFIG_KEY_BUILD_BITMAPS, isBuildBitmaps()));
+ setBitmapContiguousCommitCount(rc.getInt(CONFIG_PACK_SECTION,
+ CONFIG_KEY_BITMAP_CONTIGUOUS_COMMIT_COUNT,
+ getBitmapContiguousCommitCount()));
+ setBitmapRecentCommitCount(rc.getInt(CONFIG_PACK_SECTION,
+ CONFIG_KEY_BITMAP_RECENT_COMMIT_COUNT,
getBitmapRecentCommitCount()));
- setBitmapRecentCommitSpan(rc.getInt("pack", "bitmaprecentcommitspan", //$NON-NLS-1$ //$NON-NLS-2$
+ setBitmapRecentCommitSpan(rc.getInt(CONFIG_PACK_SECTION,
+ CONFIG_KEY_BITMAP_RECENT_COMMIT_COUNT,
getBitmapRecentCommitSpan()));
- setBitmapDistantCommitSpan(rc.getInt("pack", "bitmapdistantcommitspan", //$NON-NLS-1$ //$NON-NLS-2$
+ setBitmapDistantCommitSpan(rc.getInt(CONFIG_PACK_SECTION,
+ CONFIG_KEY_BITMAP_DISTANT_COMMIT_SPAN,
getBitmapDistantCommitSpan()));
- setBitmapExcessiveBranchCount(rc.getInt("pack", //$NON-NLS-1$
- "bitmapexcessivebranchcount", getBitmapExcessiveBranchCount())); //$NON-NLS-1$
- setBitmapInactiveBranchAgeInDays(
- rc.getInt("pack", "bitmapinactivebranchageindays", //$NON-NLS-1$ //$NON-NLS-2$
- getBitmapInactiveBranchAgeInDays()));
- setWaitPreventRacyPack(rc.getBoolean("pack", "waitpreventracypack", //$NON-NLS-1$ //$NON-NLS-2$
- isWaitPreventRacyPack()));
- setMinSizePreventRacyPack(rc.getLong("pack", "minsizepreventracypack", //$NON-NLS-1$//$NON-NLS-2$
+ setBitmapExcessiveBranchCount(rc.getInt(CONFIG_PACK_SECTION,
+ CONFIG_KEY_BITMAP_EXCESSIVE_BRANCH_COUNT,
+ getBitmapExcessiveBranchCount()));
+ setBitmapInactiveBranchAgeInDays(rc.getInt(CONFIG_PACK_SECTION,
+ CONFIG_KEY_BITMAP_INACTIVE_BRANCH_AGE_INDAYS,
+ getBitmapInactiveBranchAgeInDays()));
+ setWaitPreventRacyPack(rc.getBoolean(CONFIG_PACK_SECTION,
+ CONFIG_KEY_WAIT_PREVENT_RACYPACK, isWaitPreventRacyPack()));
+ setMinSizePreventRacyPack(rc.getLong(CONFIG_PACK_SECTION,
+ CONFIG_KEY_MIN_SIZE_PREVENT_RACYPACK,
getMinSizePreventRacyPack()));
}
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 2d406bd..994af26 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 @@
}
// 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 @@
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 216bf2c..988953b 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 @@
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 @@
}
}
+ /**
+ * 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 a082200..c9d2770 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 @@
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 @@
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 82b2818..d53bff7 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 @@
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) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
index 4831fbb..c43956e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
@@ -20,6 +20,7 @@
import java.nio.channels.FileChannel;
import java.nio.file.AtomicMoveNotSupportedException;
import java.nio.file.CopyOption;
+import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.LinkOption;
@@ -180,21 +181,31 @@
}
if (delete) {
- Throwable t = null;
+ IOException t = null;
Path p = f.toPath();
- try {
- Files.delete(p);
- return;
- } catch (FileNotFoundException e) {
- if ((options & (SKIP_MISSING | IGNORE_ERRORS)) == 0) {
- throw new IOException(MessageFormat.format(
- JGitText.get().deleteFileFailed,
- f.getAbsolutePath()), e);
+ boolean tryAgain;
+ do {
+ tryAgain = false;
+ try {
+ Files.delete(p);
+ return;
+ } catch (NoSuchFileException | FileNotFoundException e) {
+ handleDeleteException(f, e, options,
+ SKIP_MISSING | IGNORE_ERRORS);
+ return;
+ } catch (DirectoryNotEmptyException e) {
+ handleDeleteException(f, e, options, IGNORE_ERRORS);
+ return;
+ } catch (IOException e) {
+ if (!f.canWrite()) {
+ tryAgain = f.setWritable(true);
+ }
+ if (!tryAgain) {
+ t = e;
+ }
}
- return;
- } catch (IOException e) {
- t = e;
- }
+ } while (tryAgain);
+
if ((options & RETRY) != 0) {
for (int i = 1; i < 10; i++) {
try {
@@ -210,11 +221,15 @@
}
}
}
- if ((options & IGNORE_ERRORS) == 0) {
- throw new IOException(MessageFormat.format(
- JGitText.get().deleteFileFailed, f.getAbsolutePath()),
- t);
- }
+ handleDeleteException(f, t, options, IGNORE_ERRORS);
+ }
+ }
+
+ private static void handleDeleteException(File f, IOException e,
+ int allOptions, int checkOptions) throws IOException {
+ if (e != null && (allOptions & checkOptions) == 0) {
+ throw new IOException(MessageFormat.format(
+ JGitText.get().deleteFileFailed, f.getAbsolutePath()), e);
}
}
diff --git a/pom.xml b/pom.xml
index 6764644..070a1c5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -895,7 +895,7 @@
<dependency>
<groupId>org.eclipse.jdt</groupId>
<artifactId>ecj</artifactId>
- <version>3.20.0</version>
+ <version>3.21.0</version>
</dependency>
</dependencies>
</plugin>