aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jgit/.settings/.api_filters17
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/errors/PackMismatchException.java29
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java37
3 files changed, 76 insertions, 7 deletions
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters
new file mode 100644
index 0000000000..7a3dc84085
--- /dev/null
+++ b/org.eclipse.jgit/.settings/.api_filters
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.jgit" version="2">
+ <resource path="src/org/eclipse/jgit/errors/PackMismatchException.java" type="org.eclipse.jgit.errors.PackMismatchException">
+ <filter id="1142947843">
+ <message_arguments>
+ <message_argument value="5.9.1"/>
+ <message_argument value="isPermanent()"/>
+ </message_arguments>
+ </filter>
+ <filter id="1142947843">
+ <message_arguments>
+ <message_argument value="5.9.1"/>
+ <message_argument value="setPermanent(boolean)"/>
+ </message_arguments>
+ </filter>
+ </resource>
+</component>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/PackMismatchException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/PackMismatchException.java
index ad5664ceb2..5f3f0c39fd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/PackMismatchException.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/PackMismatchException.java
@@ -18,6 +18,8 @@ import java.io.IOException;
public class PackMismatchException extends IOException {
private static final long serialVersionUID = 1L;
+ private boolean permanent;
+
/**
* Construct a pack modification error.
*
@@ -27,4 +29,31 @@ public class PackMismatchException extends IOException {
public PackMismatchException(String why) {
super(why);
}
+
+ /**
+ * Set the type of the exception
+ *
+ * @param permanent
+ * whether the exception is considered permanent
+ * @since 5.9.1
+ */
+ public void setPermanent(boolean permanent) {
+ this.permanent = permanent;
+ }
+
+ /**
+ * Check if this is a permanent problem
+ *
+ * @return if this is a permanent problem and repeatedly scanning the
+ * packlist couldn't fix it
+ * @since 5.9.1
+ */
+ public boolean isPermanent() {
+ return permanent;
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + ", permanent: " + permanent; //$NON-NLS-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 9d1d457369..2131e5f670 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
@@ -89,6 +89,8 @@ public class ObjectDirectory extends FileObjectDatabase {
* handle exception is thrown */
final static int MAX_LOOSE_OBJECT_STALE_READ_ATTEMPTS = 5;
+ private static final int MAX_PACKLIST_RESCAN_ATTEMPTS = 5;
+
private final AlternateHandle handle = new AlternateHandle(this);
private final Config config;
@@ -413,7 +415,8 @@ public class ObjectDirectory extends FileObjectDatabase {
}
private ObjectLoader openPackedFromSelfOrAlternate(WindowCursor curs,
- AnyObjectId objectId, Set<AlternateHandle.Id> skips) {
+ AnyObjectId objectId, Set<AlternateHandle.Id> skips)
+ throws PackMismatchException {
ObjectLoader ldr = openPackedObject(curs, objectId);
if (ldr != null) {
return ldr;
@@ -449,9 +452,11 @@ public class ObjectDirectory extends FileObjectDatabase {
return null;
}
- ObjectLoader openPackedObject(WindowCursor curs, AnyObjectId objectId) {
+ ObjectLoader openPackedObject(WindowCursor curs, AnyObjectId objectId)
+ throws PackMismatchException {
PackList pList;
do {
+ int retries = 0;
SEARCH: for (;;) {
pList = packList.get();
for (PackFile p : pList.packs) {
@@ -462,8 +467,10 @@ public class ObjectDirectory extends FileObjectDatabase {
return ldr;
} catch (PackMismatchException e) {
// Pack was modified; refresh the entire pack list.
- if (searchPacksAgain(pList))
+ if (searchPacksAgain(pList)) {
+ retries = checkRescanPackThreshold(retries, e);
continue SEARCH;
+ }
} catch (IOException e) {
handlePackError(e, p);
}
@@ -555,7 +562,8 @@ public class ObjectDirectory extends FileObjectDatabase {
}
private long getPackedSizeFromSelfOrAlternate(WindowCursor curs,
- AnyObjectId id, Set<AlternateHandle.Id> skips) {
+ AnyObjectId id, Set<AlternateHandle.Id> skips)
+ throws PackMismatchException {
long len = getPackedObjectSize(curs, id);
if (0 <= len) {
return len;
@@ -590,9 +598,11 @@ public class ObjectDirectory extends FileObjectDatabase {
return -1;
}
- private long getPackedObjectSize(WindowCursor curs, AnyObjectId id) {
+ private long getPackedObjectSize(WindowCursor curs, AnyObjectId id)
+ throws PackMismatchException {
PackList pList;
do {
+ int retries = 0;
SEARCH: for (;;) {
pList = packList.get();
for (PackFile p : pList.packs) {
@@ -603,8 +613,10 @@ public class ObjectDirectory extends FileObjectDatabase {
return len;
} catch (PackMismatchException e) {
// Pack was modified; refresh the entire pack list.
- if (searchPacksAgain(pList))
+ if (searchPacksAgain(pList)) {
+ retries = checkRescanPackThreshold(retries, e);
continue SEARCH;
+ }
} catch (IOException e) {
handlePackError(e, p);
}
@@ -632,13 +644,14 @@ public class ObjectDirectory extends FileObjectDatabase {
@Override
void selectObjectRepresentation(PackWriter packer, ObjectToPack otp,
- WindowCursor curs) throws IOException {
+ WindowCursor curs) throws IOException {
selectObjectRepresentation(packer, otp, curs, null);
}
private void selectObjectRepresentation(PackWriter packer, ObjectToPack otp,
WindowCursor curs, Set<AlternateHandle.Id> skips) throws IOException {
PackList pList = packList.get();
+ int retries = 0;
SEARCH: for (;;) {
for (PackFile p : pList.packs) {
try {
@@ -649,6 +662,7 @@ public class ObjectDirectory extends FileObjectDatabase {
} catch (PackMismatchException e) {
// Pack was modified; refresh the entire pack list.
//
+ retries = checkRescanPackThreshold(retries, e);
pList = scanPacks(pList);
continue SEARCH;
} catch (IOException e) {
@@ -666,6 +680,15 @@ public class ObjectDirectory extends FileObjectDatabase {
}
}
+ private int checkRescanPackThreshold(int retries, PackMismatchException e)
+ throws PackMismatchException {
+ if (retries++ > MAX_PACKLIST_RESCAN_ATTEMPTS) {
+ e.setPermanent(true);
+ throw e;
+ }
+ return retries;
+ }
+
private void handlePackError(IOException e, PackFile p) {
String warnTmpl = null;
int transientErrorCount = 0;