diff options
author | Matthias Sohn <matthias.sohn@sap.com> | 2018-05-10 12:51:57 +0200 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2018-05-10 12:51:57 +0200 |
commit | 9fdc595cdddac5913a2f3d512cc7787bebc3b687 (patch) | |
tree | 16ddb311ee1a330b17d8eefec21aceb0763961b8 | |
parent | 95fc2b210f3df3a1ff5c729dbc0624e3d25d34bd (diff) | |
parent | dd9a14a762c796080f95f638c5c77b26c3e5fe11 (diff) | |
download | jgit-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>
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); } } |