aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
authorMatthias Sohn <matthias.sohn@sap.com>2023-01-13 19:31:18 +0100
committerMatthias Sohn <matthias.sohn@sap.com>2023-01-13 19:31:18 +0100
commit9eef6790cff74ca95bcebf388d46b7a400eac325 (patch)
tree4aaffb4a2f5ee88b28722736863ad232ee0c8c72 /org.eclipse.jgit
parent62ed46da16fb885180190f671ec2b6693bc440c3 (diff)
parent21b2aef0aa9f71306733c7724f7ffff3e86206de (diff)
downloadjgit-9eef6790cff74ca95bcebf388d46b7a400eac325.tar.gz
jgit-9eef6790cff74ca95bcebf388d46b7a400eac325.zip
Merge branch 'stable-6.1' into stable-6.2
* stable-6.1: Cache trustFolderStat/trustPackedRefsStat value per-instance Refresh 'objects' dir and retry if a loose object is not found Change-Id: I9e876f72f735f58bf02c7862a3d8e657fc46a7b9
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LooseObjects.java71
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java23
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java21
4 files changed, 86 insertions, 31 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LooseObjects.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LooseObjects.java
index 33621a1e9f..b9af83d24d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LooseObjects.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LooseObjects.java
@@ -14,6 +14,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.StandardCopyOption;
@@ -24,6 +25,8 @@ import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.internal.storage.file.FileObjectDatabase.InsertLooseObjectResult;
import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
@@ -52,15 +55,22 @@ class LooseObjects {
private final UnpackedObjectCache unpackedObjectCache;
+ private final boolean trustFolderStat;
+
/**
* Initialize a reference to an on-disk object directory.
*
+ * @param config
+ * configuration for the loose objects handler.
* @param dir
* the location of the <code>objects</code> directory.
*/
- LooseObjects(File dir) {
+ LooseObjects(Config config, File dir) {
directory = dir;
unpackedObjectCache = new UnpackedObjectCache();
+ trustFolderStat = config.getBoolean(
+ ConfigConstants.CONFIG_CORE_SECTION,
+ ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true);
}
/**
@@ -98,6 +108,19 @@ class LooseObjects {
* @return {@code true} if the specified object is stored as a loose object.
*/
boolean has(AnyObjectId objectId) {
+ boolean exists = hasWithoutRefresh(objectId);
+ if (trustFolderStat || exists) {
+ return exists;
+ }
+ try (InputStream stream = Files.newInputStream(directory.toPath())) {
+ // refresh directory to work around NFS caching issue
+ } catch (IOException e) {
+ return false;
+ }
+ return hasWithoutRefresh(objectId);
+ }
+
+ private boolean hasWithoutRefresh(AnyObjectId objectId) {
return fileFor(objectId).exists();
}
@@ -183,6 +206,22 @@ class LooseObjects {
*/
ObjectLoader getObjectLoader(WindowCursor curs, File path, AnyObjectId id)
throws IOException {
+ try {
+ return getObjectLoaderWithoutRefresh(curs, path, id);
+ } catch (FileNotFoundException e) {
+ if (trustFolderStat) {
+ throw e;
+ }
+ try (InputStream stream = Files
+ .newInputStream(directory.toPath())) {
+ // refresh directory to work around NFS caching issues
+ }
+ return getObjectLoaderWithoutRefresh(curs, path, id);
+ }
+ }
+
+ private ObjectLoader getObjectLoaderWithoutRefresh(WindowCursor curs,
+ File path, AnyObjectId id) throws IOException {
try (FileInputStream in = new FileInputStream(path)) {
unpackedObjectCache().add(id);
return UnpackedObject.open(in, path, id, curs);
@@ -203,16 +242,34 @@ class LooseObjects {
}
long getSize(WindowCursor curs, AnyObjectId id) throws IOException {
+ try {
+ return getSizeWithoutRefresh(curs, id);
+ } catch (FileNotFoundException noFile) {
+ try {
+ if (trustFolderStat) {
+ throw noFile;
+ }
+ try (InputStream stream = Files
+ .newInputStream(directory.toPath())) {
+ // refresh directory to work around NFS caching issue
+ }
+ return getSizeWithoutRefresh(curs, id);
+ } catch (FileNotFoundException e) {
+ if (fileFor(id).exists()) {
+ throw noFile;
+ }
+ unpackedObjectCache().remove(id);
+ return -1;
+ }
+ }
+ }
+
+ private long getSizeWithoutRefresh(WindowCursor curs, AnyObjectId id)
+ throws IOException {
File f = fileFor(id);
try (FileInputStream in = new FileInputStream(f)) {
unpackedObjectCache().add(id);
return UnpackedObject.getSize(in, id, curs);
- } catch (FileNotFoundException noFile) {
- if (f.exists()) {
- throw noFile;
- }
- unpackedObjectCache().remove(id);
- return -1;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
index 06c8cad3ac..531fd78cd0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
@@ -120,7 +120,7 @@ public class ObjectDirectory extends FileObjectDatabase {
File packDirectory = new File(objects, "pack"); //$NON-NLS-1$
File preservedDirectory = new File(packDirectory, "preserved"); //$NON-NLS-1$
alternatesFile = new File(objects, Constants.INFO_ALTERNATES);
- loose = new LooseObjects(objects);
+ loose = new LooseObjects(config, objects);
packed = new PackDirectory(config, packDirectory);
preserved = new PackDirectory(config, preservedDirectory);
this.fs = fs;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java
index f32909f44d..a7f28c6778 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java
@@ -63,12 +63,12 @@ class PackDirectory {
private static final PackList NO_PACKS = new PackList(FileSnapshot.DIRTY,
new Pack[0]);
- private final Config config;
-
private final File directory;
private final AtomicReference<PackList> packList;
+ private final boolean trustFolderStat;
+
/**
* Initialize a reference to an on-disk 'pack' directory.
*
@@ -78,9 +78,16 @@ class PackDirectory {
* the location of the {@code pack} directory.
*/
PackDirectory(Config config, File directory) {
- this.config = config;
this.directory = directory;
packList = new AtomicReference<>(NO_PACKS);
+
+ // Whether to trust the pack folder's modification time. If set to false
+ // we will always scan the .git/objects/pack folder to check for new
+ // pack files. If set to true (default) we use the folder's size,
+ // modification time, and key (inode) and assume that no new pack files
+ // can be in this folder if these attributes have not changed.
+ trustFolderStat = config.getBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+ ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true);
}
/**
@@ -331,16 +338,6 @@ class PackDirectory {
}
boolean searchPacksAgain(PackList old) {
- // Whether to trust the pack folder's modification time. If set
- // to false we will always scan the .git/objects/pack folder to
- // check for new pack files. If set to true (default) we use the
- // lastmodified attribute of the folder and assume that no new
- // pack files can be in this folder if his modification time has
- // not changed.
- boolean trustFolderStat = config.getBoolean(
- ConfigConstants.CONFIG_CORE_SECTION,
- ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true);
-
return ((!trustFolderStat) || old.snapshot.isModified(directory))
&& old != scanPacks(old);
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
index 94a377fd3f..348a22ca64 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
@@ -179,6 +179,10 @@ public class RefDirectory extends RefDatabase {
private List<Integer> retrySleepMs = RETRY_SLEEP_MS;
+ private final boolean trustFolderStat;
+
+ private final TrustPackedRefsStat trustPackedRefsStat;
+
RefDirectory(FileRepository db) {
final FS fs = db.getFS();
parent = db;
@@ -190,6 +194,13 @@ public class RefDirectory extends RefDatabase {
looseRefs.set(RefList.<LooseRef> emptyList());
packedRefs.set(NO_PACKED_REFS);
+ trustFolderStat = db.getConfig()
+ .getBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+ ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true);
+ trustPackedRefsStat = db.getConfig()
+ .getEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
+ ConfigConstants.CONFIG_KEY_TRUST_PACKED_REFS_STAT,
+ TrustPackedRefsStat.UNSET);
}
Repository getRepository() {
@@ -891,16 +902,6 @@ public class RefDirectory extends RefDatabase {
}
PackedRefList getPackedRefs() throws IOException {
- boolean trustFolderStat = getRepository().getConfig().getBoolean(
- ConfigConstants.CONFIG_CORE_SECTION,
- ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true);
- TrustPackedRefsStat trustPackedRefsStat =
- getRepository().getConfig().getEnum(
- ConfigConstants.CONFIG_CORE_SECTION,
- null,
- ConfigConstants.CONFIG_KEY_TRUST_PACKED_REFS_STAT,
- TrustPackedRefsStat.UNSET);
-
final PackedRefList curList = packedRefs.get();
switch (trustPackedRefsStat) {