d45219ba
We can't add this method to the super class StoredConfig since that abstracts from filesystem storage. MockSystemReader.MockConfig is a StoredConfig and is also used by tests for dfs based storage. Hence remove this leaky abstraction. This implies we always use the fallback FileStoreAttributes which means a config file modification is considered racy within the first 2 seconds. This should not be an issue since typically configs change rarely and re-reading a config within the racy period is relatively cheap since configs are small. Change-Id: Ia2615addc24a7cadf3c566ee842c6f4f07e159a5 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>tags/v5.1.9.201908210455-r
@@ -78,14 +78,6 @@ | |||
</message_arguments> | |||
</filter> | |||
</resource> | |||
<resource path="src/org/eclipse/jgit/storage/file/FileBasedConfig.java" type="org.eclipse.jgit.storage.file.FileBasedConfig"> | |||
<filter id="1142947843"> | |||
<message_arguments> | |||
<message_argument value="5.1.9"/> | |||
<message_argument value="load(boolean)"/> | |||
</message_arguments> | |||
</filter> | |||
</resource> | |||
<resource path="src/org/eclipse/jgit/storage/pack/PackConfig.java" type="org.eclipse.jgit.storage.pack.PackConfig"> | |||
<filter id="336658481"> | |||
<message_arguments> |
@@ -149,37 +149,13 @@ public class FileBasedConfig extends StoredConfig { | |||
*/ | |||
@Override | |||
public void load() throws IOException, ConfigInvalidException { | |||
load(true); | |||
} | |||
/** | |||
* Load the configuration as a Git text style configuration file. | |||
* <p> | |||
* If the file does not exist, this configuration is cleared, and thus | |||
* behaves the same as though the file exists, but is empty. | |||
* | |||
* @param useFileSnapshotWithConfig | |||
* if {@code true} use the FileSnapshot with config, otherwise | |||
* use it without config | |||
* @throws IOException | |||
* if IO failed | |||
* @throws ConfigInvalidException | |||
* if config is invalid | |||
* @since 5.1.9 | |||
*/ | |||
public void load(boolean useFileSnapshotWithConfig) | |||
throws IOException, ConfigInvalidException { | |||
final int maxStaleRetries = 5; | |||
int retries = 0; | |||
while (true) { | |||
final FileSnapshot oldSnapshot = snapshot; | |||
final FileSnapshot newSnapshot; | |||
if (useFileSnapshotWithConfig) { | |||
newSnapshot = FileSnapshot.save(getFile()); | |||
} else { | |||
// don't use config in this snapshot to avoid endless recursion | |||
newSnapshot = FileSnapshot.saveNoConfig(getFile()); | |||
} | |||
// don't use config in this snapshot to avoid endless recursion | |||
newSnapshot = FileSnapshot.saveNoConfig(getFile()); | |||
try { | |||
final byte[] in = IO.readFully(getFile()); | |||
final ObjectId newHash = hash(in); |
@@ -100,7 +100,7 @@ import org.eclipse.jgit.internal.storage.file.FileSnapshot; | |||
import org.eclipse.jgit.lib.ConfigConstants; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.storage.file.FileBasedConfig; | |||
import org.eclipse.jgit.lib.StoredConfig; | |||
import org.eclipse.jgit.treewalk.FileTreeIterator.FileEntry; | |||
import org.eclipse.jgit.treewalk.FileTreeIterator.FileModeStrategy; | |||
import org.eclipse.jgit.treewalk.WorkingTreeIterator.Entry; | |||
@@ -510,17 +510,17 @@ public abstract class FS { | |||
private static Optional<FileStoreAttributes> readFromConfig( | |||
FileStore s) { | |||
FileBasedConfig userConfig = SystemReader.getInstance() | |||
StoredConfig userConfig = SystemReader.getInstance() | |||
.openUserConfig(null, FS.DETECTED); | |||
try { | |||
userConfig.load(false); | |||
userConfig.load(); | |||
} catch (IOException e) { | |||
LOG.error(MessageFormat.format(JGitText.get().readConfigFailed, | |||
userConfig.getFile().getAbsolutePath()), e); | |||
userConfig), e); | |||
} catch (ConfigInvalidException e) { | |||
LOG.error(MessageFormat.format( | |||
JGitText.get().repositoryConfigFileInvalid, | |||
userConfig.getFile().getAbsolutePath(), | |||
userConfig, | |||
e.getMessage())); | |||
} | |||
String key = getConfigKey(s); | |||
@@ -544,7 +544,7 @@ public abstract class FS { | |||
private static void saveToConfig(FileStore s, | |||
FileStoreAttributes c) { | |||
FileBasedConfig userConfig = SystemReader.getInstance() | |||
StoredConfig userConfig = SystemReader.getInstance() | |||
.openUserConfig(null, FS.DETECTED); | |||
long resolution = c.getFsTimestampResolution().toNanos(); | |||
TimeUnit resolutionUnit = getUnit(resolution); | |||
@@ -562,7 +562,7 @@ public abstract class FS { | |||
String key = getConfigKey(s); | |||
while (!succeeded && retries < max_retries) { | |||
try { | |||
userConfig.load(false); | |||
userConfig.load(); | |||
userConfig.setString( | |||
ConfigConstants.CONFIG_FILESYSTEM_SECTION, key, | |||
ConfigConstants.CONFIG_KEY_TIMESTAMP_RESOLUTION, | |||
@@ -581,7 +581,7 @@ public abstract class FS { | |||
// race with another thread, wait a bit and try again | |||
try { | |||
LOG.warn(MessageFormat.format(JGitText.get().cannotLock, | |||
userConfig.getFile().getAbsolutePath())); | |||
userConfig)); | |||
retries++; | |||
Thread.sleep(20); | |||
} catch (InterruptedException e1) { | |||
@@ -589,13 +589,11 @@ public abstract class FS { | |||
} | |||
} catch (IOException e) { | |||
LOG.error(MessageFormat.format( | |||
JGitText.get().cannotSaveConfig, | |||
userConfig.getFile().getAbsolutePath()), e); | |||
JGitText.get().cannotSaveConfig, userConfig), e); | |||
} catch (ConfigInvalidException e) { | |||
LOG.error(MessageFormat.format( | |||
JGitText.get().repositoryConfigFileInvalid, | |||
userConfig.getFile().getAbsolutePath(), | |||
e.getMessage())); | |||
userConfig, e.getMessage())); | |||
} | |||
} | |||
} |