summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.mvn/maven.config2
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java29
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java50
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/io/NullMessageDigest.java58
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java6
5 files changed, 132 insertions, 13 deletions
diff --git a/.mvn/maven.config b/.mvn/maven.config
index ebbe28853d..3944d880ef 100644
--- a/.mvn/maven.config
+++ b/.mvn/maven.config
@@ -1 +1 @@
--T 1C
+-T1C
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java
index 0fca652906..618ccc0a0c 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java
@@ -17,19 +17,48 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
+import java.io.IOException;
import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.Collection;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.junit.MockSystemReader;
import org.eclipse.jgit.junit.RepositoryTestCase;
+import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.SystemReader;
+import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+@RunWith(Parameterized.class)
public class DirCacheBasicTest extends RepositoryTestCase {
+ @Parameter(0)
+ public boolean skipHash;
+
+ @Parameters(name = "skipHash: {0}")
+ public static Collection<Boolean[]> getSkipHashValues() {
+ return Arrays
+ .asList(new Boolean[][] { { Boolean.TRUE },
+ { Boolean.FALSE } });
+ }
+
+ @Before
+ public void setup() throws IOException {
+ FileBasedConfig cfg = db.getConfig();
+ cfg.setBoolean(ConfigConstants.CONFIG_INDEX_SECTION, null,
+ ConfigConstants.CONFIG_KEY_SKIPHASH, skipHash);
+ cfg.save();
+ }
+
@Test
public void testReadMissing_RealIndex() throws Exception {
final File idx = new File(db.getDirectory(), "index");
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java
index 03da61583d..e56061223c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java
@@ -40,6 +40,7 @@ import org.eclipse.jgit.events.IndexChangedListener;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.internal.storage.file.FileSnapshot;
import org.eclipse.jgit.internal.storage.file.LockFile;
+import org.eclipse.jgit.internal.storage.io.NullMessageDigest;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Config.ConfigEnum;
@@ -327,6 +328,9 @@ public class DirCache {
/** If we read this index from disk, the original format. */
private DirCacheVersion version;
+ /** Whether to skip computing and checking the index checksum */
+ private boolean skipHash;
+
/**
* Create a new in-core index representation.
* <p>
@@ -446,7 +450,8 @@ public class DirCache {
private void readFrom(InputStream inStream) throws IOException,
CorruptObjectException {
final BufferedInputStream in = new BufferedInputStream(inStream);
- final MessageDigest md = Constants.newMessageDigest();
+ readConfig();
+ MessageDigest md = newMessageDigest();
// Read the index header and verify we understand it.
//
@@ -543,8 +548,12 @@ public class DirCache {
}
readIndexChecksum = md.digest();
- if (!Arrays.equals(readIndexChecksum, hdr)) {
- throw new CorruptObjectException(JGitText.get().DIRCChecksumMismatch);
+ if (!(skipHash
+ || Arrays.equals(readIndexChecksum, hdr)
+ || Arrays.equals(NullMessageDigest.getInstance().digest(),
+ hdr))) {
+ throw new CorruptObjectException(
+ JGitText.get().DIRCChecksumMismatch);
}
}
@@ -627,15 +636,9 @@ public class DirCache {
}
void writeTo(File dir, OutputStream os) throws IOException {
- final MessageDigest foot = Constants.newMessageDigest();
- final DigestOutputStream dos = new DigestOutputStream(os, foot);
-
- if (version == null && this.repository != null) {
- // A new DirCache is being written.
- DirCacheConfig config = repository.getConfig()
- .get(DirCacheConfig::new);
- version = config.getIndexVersion();
- }
+ readConfig();
+ MessageDigest foot = newMessageDigest();
+ DigestOutputStream dos = new DigestOutputStream(os, foot);
if (version == null
|| version == DirCacheVersion.DIRC_VERSION_MINIMUM) {
version = DirCacheVersion.DIRC_VERSION_MINIMUM;
@@ -707,6 +710,22 @@ public class DirCache {
os.close();
}
+ private void readConfig() {
+ if (version == null && this.repository != null) {
+ DirCacheConfig config = repository.getConfig()
+ .get(DirCacheConfig::new);
+ version = config.getIndexVersion();
+ skipHash = config.isSkipHash();
+ }
+ }
+
+ private MessageDigest newMessageDigest() {
+ if (skipHash) {
+ return NullMessageDigest.getInstance();
+ }
+ return Constants.newMessageDigest();
+ }
+
/**
* Commit this change and release the lock.
* <p>
@@ -1071,6 +1090,8 @@ public class DirCache {
private final DirCacheVersion indexVersion;
+ private final boolean skipHash;
+
public DirCacheConfig(Config cfg) {
boolean manyFiles = cfg.getBoolean(
ConfigConstants.CONFIG_FEATURE_SECTION,
@@ -1080,11 +1101,16 @@ public class DirCache {
ConfigConstants.CONFIG_KEY_VERSION,
manyFiles ? DirCacheVersion.DIRC_VERSION_PATHCOMPRESS
: DirCacheVersion.DIRC_VERSION_EXTENDED);
+ skipHash = cfg.getBoolean(ConfigConstants.CONFIG_INDEX_SECTION,
+ ConfigConstants.CONFIG_KEY_SKIPHASH, false);
}
public DirCacheVersion getIndexVersion() {
return indexVersion;
}
+ public boolean isSkipHash() {
+ return skipHash;
+ }
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/io/NullMessageDigest.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/io/NullMessageDigest.java
new file mode 100644
index 0000000000..ea5877ffff
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/io/NullMessageDigest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023, SAP SE and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.io;
+
+import java.security.MessageDigest;
+
+import org.eclipse.jgit.lib.Constants;
+
+/**
+ * Dummy message digest consisting of only null bytes with the length of an
+ * ObjectId. This class can be used to skip computing a real digest.
+ */
+public final class NullMessageDigest extends MessageDigest {
+ private static final byte[] digest = new byte[Constants.OBJECT_ID_LENGTH];
+
+ private static final NullMessageDigest INSTANCE = new NullMessageDigest();
+
+ /**
+ * Get the only instance of NullMessageDigest
+ *
+ * @return the only instance of NullMessageDigest
+ */
+ public static MessageDigest getInstance() {
+ return INSTANCE;
+ }
+
+ private NullMessageDigest() {
+ super("null"); //$NON-NLS-1$
+ }
+
+ @Override
+ protected void engineUpdate(byte input) {
+ // empty
+ }
+
+ @Override
+ protected void engineUpdate(byte[] input, int offset, int len) {
+ // empty
+ }
+
+ @Override
+ protected byte[] engineDigest() {
+ return digest;
+ }
+
+ @Override
+ protected void engineReset() {
+ // empty
+ }
+}
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 96f3198cef..5c48c7a08e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -449,6 +449,12 @@ public final class ConfigConstants {
public static final String CONFIG_KEY_INDEXVERSION = "indexversion";
/**
+ * The "skiphash" key
+ * @since 5.13.2
+ */
+ public static final String CONFIG_KEY_SKIPHASH = "skiphash";
+
+ /**
* The "hidedotfiles" key
* @since 3.5
*/