summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Sohn <matthias.sohn@sap.com>2018-05-10 12:51:57 +0200
committerMatthias Sohn <matthias.sohn@sap.com>2018-05-10 12:51:57 +0200
commit9fdc595cdddac5913a2f3d512cc7787bebc3b687 (patch)
tree16ddb311ee1a330b17d8eefec21aceb0763961b8
parent95fc2b210f3df3a1ff5c729dbc0624e3d25d34bd (diff)
parentdd9a14a762c796080f95f638c5c77b26c3e5fe11 (diff)
downloadjgit-9fdc595cdddac5913a2f3d512cc7787bebc3b687.tar.gz
jgit-9fdc595cdddac5913a2f3d512cc7787bebc3b687.zip
Merge branch 'stable-4.9' into stable-4.10
* stable-4.9: Retry stale file handles on .git/config file Change-Id: I6db7256dbd1c71b23e1231809642ca21e996e066 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
-rw-r--r--org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java84
3 files changed, 56 insertions, 30 deletions
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
index 45a6af3755..b29383e481 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -133,6 +133,7 @@ compressingObjects=Compressing objects
configSubsectionContainsNewline=config subsection name contains newline
configSubsectionContainsNullByte=config subsection name contains byte 0x00
configValueContainsNullByte=config value contains byte 0x00
+configHandleIsStale=config file handle is stale, {0}. retry
connectionFailed=connection failed
connectionTimeOut=Connection time out: {0}
contextMustBeNonNegative=context must be >= 0
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
index e23d2534b6..4c16fe71fb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -194,6 +194,7 @@ public class JGitText extends TranslationBundle {
/***/ public String configSubsectionContainsNewline;
/***/ public String configSubsectionContainsNullByte;
/***/ public String configValueContainsNullByte;
+ /***/ public String configHandleIsStale;
/***/ public String connectionFailed;
/***/ public String connectionTimeOut;
/***/ public String contextMustBeNonNegative;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java
index 9927daf3d5..3f064e3341 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java
@@ -66,13 +66,19 @@ import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.FileUtils;
import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.RawParseUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* The configuration file that is stored in the file of the file system.
*/
public class FileBasedConfig extends StoredConfig {
+ private final static Logger LOG = LoggerFactory
+ .getLogger(FileBasedConfig.class);
+
private final File configFile;
private final FS fs;
@@ -141,40 +147,58 @@ public class FileBasedConfig extends StoredConfig {
*/
@Override
public void load() throws IOException, ConfigInvalidException {
- final FileSnapshot oldSnapshot = snapshot;
- final FileSnapshot newSnapshot = FileSnapshot.save(getFile());
- try {
- final byte[] in = IO.readFully(getFile());
- final ObjectId newHash = hash(in);
- if (hash.equals(newHash)) {
- if (oldSnapshot.equals(newSnapshot))
- oldSnapshot.setClean(newSnapshot);
- else
- snapshot = newSnapshot;
- } else {
- final String decoded;
- if (isUtf8(in)) {
- decoded = RawParseUtils.decode(RawParseUtils.UTF8_CHARSET,
- in, 3, in.length);
- utf8Bom = true;
+ final int maxStaleRetries = 5;
+ int retries = 0;
+ while (true) {
+ final FileSnapshot oldSnapshot = snapshot;
+ final FileSnapshot newSnapshot = FileSnapshot.save(getFile());
+ try {
+ final byte[] in = IO.readFully(getFile());
+ final ObjectId newHash = hash(in);
+ if (hash.equals(newHash)) {
+ if (oldSnapshot.equals(newSnapshot)) {
+ oldSnapshot.setClean(newSnapshot);
+ } else {
+ snapshot = newSnapshot;
+ }
} else {
- decoded = RawParseUtils.decode(in);
+ final String decoded;
+ if (isUtf8(in)) {
+ decoded = RawParseUtils.decode(
+ RawParseUtils.UTF8_CHARSET, in, 3, in.length);
+ utf8Bom = true;
+ } else {
+ decoded = RawParseUtils.decode(in);
+ }
+ fromText(decoded);
+ snapshot = newSnapshot;
+ hash = newHash;
}
- fromText(decoded);
+ return;
+ } catch (FileNotFoundException noFile) {
+ if (configFile.exists()) {
+ throw noFile;
+ }
+ clear();
snapshot = newSnapshot;
- hash = newHash;
- }
- } catch (FileNotFoundException noFile) {
- if (configFile.exists()) {
- throw noFile;
+ return;
+ } catch (IOException e) {
+ if (FileUtils.isStaleFileHandle(e)
+ && retries < maxStaleRetries) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(MessageFormat.format(
+ JGitText.get().configHandleIsStale,
+ Integer.valueOf(retries)), e);
+ }
+ retries++;
+ continue;
+ }
+ throw new IOException(MessageFormat
+ .format(JGitText.get().cannotReadFile, getFile()), e);
+ } catch (ConfigInvalidException e) {
+ throw new ConfigInvalidException(MessageFormat
+ .format(JGitText.get().cannotReadFile, getFile()), e);
}
- clear();
- snapshot = newSnapshot;
- } catch (IOException e) {
- throw new IOException(MessageFormat
- .format(JGitText.get().cannotReadFile, getFile()), e);
- } catch (ConfigInvalidException e) {
- throw new ConfigInvalidException(MessageFormat.format(JGitText.get().cannotReadFile, getFile()), e);
}
}